如何在 PySpark 中根据不同数据框的唯一列值复制数值。

3

我有一个类似于以下的数据框:

df1 = 
AA  BB  CC  DD
1   X   Y   Z
2   M   N   O
3   P   Q   R

我有另一个类似的数据框:

df2 =
BB  CC  DD
G   K   O
H   L   P
I   M   Q

我想要为df1的每一个不同的'AA'列的值复制df2的所有列和行,并将结果作为df返回:
df = 
AA  BB  CC  DD
1   X   Y   Z
1   G   K   O
1   H   L   P
1   I   M   Q
2   M   N   O
2   G   K   O
2   H   L   P
2   I   M   Q
3   P   Q   R
3   G   K   O
3   H   L   P
3   I   M   Q

我现在正在做的是:

AAs = df1.select("AA").distinct().rdd.flatMap(lambda x: x).collect()
out= []
for i in AAs:
  dff = df1.filter(col('AA')==i)
  temp_df = (df1.orderBy(rand())
        .withColumn('AA', lit(i))
        )
  out.append(temp_df)
df = reduce(DataFrame.unionAll, out)

这个过程非常耗时,而且由于这些是模拟数据框,所以会导致集群失败。有没有Pyspark的方法可以解决这个问题?提前感谢。


这是一个交叉合并。我不确定如何在Pyspark中执行交叉合并。如果需要,您可以为每个数据帧分配一个临时常量键,然后在该键上进行合并。 - Quang Hoang
你的文本/示例没有展示如何处理AA列上的重复项,因为没有重复项。 - ScootCork
1个回答

2

这样做可以:

resultDf= df.select("AA")\
.crossJoin(df2)\
.union(df)

# No Need to order the actual result, this is just for displaying this example.
resultDf.orderBy("AA").show()

虽然这仍然是一个巨大的操作,可能会在集群上产生高昂的费用。

输入

DF1:

+---+---+---+---+
| AA| BB| CC| DD|
+---+---+---+---+
|  1|  X|  Y|  Z|
|  2|  M|  N|  O|
|  3|  P|  Q|  R|
+---+---+---+---+

DF2:

+---+---+---+
| BB| CC| DD|
+---+---+---+
|  G|  K|  O|
|  H|  L|  P|
|  I|  M|  Q|
+---+---+---+

输出:

+---+---+---+---+
| AA| BB| CC| DD|
+---+---+---+---+
|  1|  G|  K|  O|
|  1|  X|  Y|  Z|
|  1|  I|  M|  Q|
|  1|  H|  L|  P|
|  2|  M|  N|  O|
|  2|  I|  M|  Q|
|  2|  H|  L|  P|
|  2|  G|  K|  O|
|  3|  P|  Q|  R|
|  3|  I|  M|  Q|
|  3|  H|  L|  P|
|  3|  G|  K|  O|
+---+---+---+---+

1
这仍然比迭代方法上的union all更快。谢谢! - Strayhorn

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接