如何在数据框列表(可能为空)中应用内部连接来提高性能



我知道这个问题在这里也被问到过,但是没有人提出当reduce中的一个或两个数据框为空的情况。在这种情况下,执行内部连接的最终结果将始终为空

如果我有:

dfList = List( 
+--------+-------------+  +--------+-------------+ +--------+--------+ +--------+--------+
|    ID  |     A       |   ID      |     B       | |   ID   |     C  | |   ID   |   D    |
+--------+-------------+  +--------+-------------+ +--------+--------+ +--------+--------+
|    9574|            F|  |    9574|       005912| |    9574| 2016022| |    9574|      VD|
|    9576|            F|  |    9576|       005912| |    9576| 2016022| |    9576|      VD|
|    9578|            F|  |    9578|       005912| |    9578| 2016022| |    9578|      VD|
|    9580|            F|  |    9580|       005912| |    9580| 2016022| |    9580|      VD|
|    9582|            F|  |    9582|       005912| |    9582| 2016022| |    9582|      VD|
+--------+-------------+, +--------+-------------+,+--------+--------+,+--------+--------+ 
)

,我想把这个列表减少到一个数据帧,我可以很容易地做到:

listDataFrames.reduce(
(df1, df2) =>
df1.join(df2, Seq("ID")).localCheckpoint(true)
)

无论连接是什么(内部连接、左连接还是右连接),如果前两个数据框中有一个为空,则最终结果将为空。

一种可能是:

listDataFrames.filter(!_.rdd.isEmpty())

,但它需要很多时间,所以它在性能方面不是很好。你有什么建议吗?

如果你是在Spark 3.1上,你实际上可以使用unionByName &集团通过

df1.unionByName(df2, allowMissingColumns=True).grouby("ID","A","B","C","D")

在其他版本中,你可以做类似的事情,但我还没有测试过性能:(并且有一个问题,它只适用于数字字段,很可能你必须来回做一些转换。)

df2.select(
df2.ID, 
df2.B.alias("col1"), 
f.lit("B").alias("table"))
.union(
df1.select(
df1.ID, 
df1.A.alias("col1"), 
f.lit("A")))
.groupBy("ID")
.pivot("table")
.max("col1")
.show()

最新更新