Python 具有GroupedData的pyspark笛卡尔积(交叉连接)

Python 具有GroupedData的pyspark笛卡尔积(交叉连接),python,pyspark,user-defined-functions,cartesian-product,cross-join,Python,Pyspark,User Defined Functions,Cartesian Product,Cross Join,我有一个Pypark数据框 +---+----+----+ |key|col1|col2| +---+----+----+ |a |5.4 | 1| |a |6.5 | 2| |b |7.5 | 3| |b |4.5 | 4| |c |6.4 | 1| +--------+----+ 我想做笛卡尔积,但不是在每一行之间,而是在每一个groupby(“key”)之间,然后对其应用一些python函数。 也就是说,先进行groupby(“键”),然后对每个Groupe

我有一个Pypark数据框

+---+----+----+
|key|col1|col2|
+---+----+----+
|a  |5.4 |   1|
|a  |6.5 |   2|
|b  |7.5 |   3|
|b  |4.5 |   4|
|c  |6.4 |   1|
+--------+----+
我想做笛卡尔积,但不是在每一行之间,而是在每一个groupby(“key”)之间,然后对其应用一些python函数。 也就是说,先进行groupby(“键”),然后对每个GroupedData(a与b、a与c、b与c)进行笛卡尔积(交叉连接)

预期输出应为具有预定义方案的数据帧

schema = StructType([
    StructField("some_col_1", StringType(), False),
    StructField("some_col_2", StringType(), False)
])
因此,自定义函数应该类似于:

def custom_func(df_1: pd.DataFrame, df_2: pd.DataFrame) -> pd.DataFrame

或者(可以是spark数据帧而不是python数据帧):

我尝试了两个groupby,然后使用cogroup:

group1 = df.groupby("key")
group2 = df.groupby("key")
res = group1.cogroup(group2).applyInPandas(custom_func, schema)
但它不是笛卡尔积。 我尝试使用交叉连接,但它只应用数据帧。如何将其应用于GroupedData? 有什么办法做这件事吗

编辑: 添加图片以更好地解释问题

作为第一步,您可以执行交叉连接并过滤键不同的行:

df2 = df.alias('a').join(
    df.alias('b'), 
    F.expr('a.key < b.key')
).toDF(
    *[c+'_a' for c in df.columns], 
    *[c+'_b' for c in df.columns])

df2.show()
+-----+------+------+-----+------+------+
|key_a|col1_a|col2_a|key_b|col1_b|col2_b|
+-----+------+------+-----+------+------+
|    a|   5.4|     1|    b|   7.5|     3|
|    a|   5.4|     1|    b|   4.5|     4|
|    a|   5.4|     1|    c|   6.4|     1|
|    a|   6.5|     2|    b|   7.5|     3|
|    a|   6.5|     2|    b|   4.5|     4|
|    a|   6.5|     2|    c|   6.4|     1|
|    b|   7.5|     3|    c|   6.4|     1|
|    b|   4.5|     4|    c|   6.4|     1|
+-----+------+------+-----+------+------+

你的预期产量是多少?您将如何在这两个组上应用自定义函数?你能提供更多细节吗?@mck这是一个虚构的例子,我的自定义函数很复杂,所以我没有把它包括在问题中。从每个交叉连接中,我需要返回一个数据帧(使用预定义的方案)。不确定还需要提供哪些其他细节“^^请阅读如何创建ok,阅读它,但仍然缺少哪些信息?我回答什么是预期输出,如何在两个组上应用自定义函数是问题的一部分,使用cogroup是一个选项,但任何其他方法都可以工作。您没有提供预期输出,也没有提供函数。问题是我不需要在每一行上都执行自定义函数,函数需要获得整个GroupedData(参见我添加的图片)。然后您可以在
a.key
b.key
上进行分组,并对您现在要使用的每个组应用您的函数:res=group1.cogroup(group2.applyinpandes(自定义函数,模式),对吗?感觉像是一个效率不高的解决方案。实际上,我的数据集并不小,我有大约300个不同的键和100多个列。你能想出另一种解决方案吗?我认为最好将数据分组,然后尽可能进行笛卡尔积。不,只需通过a.key和b.key进行简单分组,然后应用Pandasi:df2=df.alias('a').join(df.alias('b')、F.expr('a.keydf2 = df.alias('a').join( df.alias('b'), F.expr('a.key < b.key') ).toDF( *[c+'_a' for c in df.columns], *[c+'_b' for c in df.columns]) df2.show() +-----+------+------+-----+------+------+ |key_a|col1_a|col2_a|key_b|col1_b|col2_b| +-----+------+------+-----+------+------+ | a| 5.4| 1| b| 7.5| 3| | a| 5.4| 1| b| 4.5| 4| | a| 5.4| 1| c| 6.4| 1| | a| 6.5| 2| b| 7.5| 3| | a| 6.5| 2| b| 4.5| 4| | a| 6.5| 2| c| 6.4| 1| | b| 7.5| 3| c| 6.4| 1| | b| 4.5| 4| c| 6.4| 1| +-----+------+------+-----+------+------+
df2.groupBy('key_a', 'key_b').applyInPandas(...)