Spark中的groupBy替代

时间:2018-06-04 17:54:00

标签: scala apache-spark grouping shuffle window-functions

我有一个带有下一个信息的Dataframe df:

id   json_data
1    {a: "1", b: "2"} 
1    {a: "1", b: "3"} 
1    {a: "1", b: "4"}
2    {a: "1", b: "2"} 
2    {a: "1", b: "6"}

我需要下一个最终结果:

id   json_data
1    [{a: "1", b: "2"},{a: "1", b: "3"},{a: "1", b: "4"}]
2    [{a: "1", b: "2"},{a: "1", b: "6"}]

我尝试了两种不同的方法,分别使用Window函数和groupBy。通过这两种方法,我得到了理想的结果。

1º方法:

var user_window = Window.partitionBy("id").orderBy("id")
val df2 = df.withColumn("json_data",
    collect_list($"json_data").over(user_window))
          .withColumn("rank", row_number().over(user_window))
          .where("rank = 1")

2º方法:

val df2 = df.groupBy(df("id")).agg(collect_list($"json_data").as("json_data"))

通过这两种方法,我获得了相同的性能。但是阅读有关Spark的文档,似乎这两种方法效率都不高,因为具有相同密钥的行将需要穿过群集(洗牌)才能在一起。我正在展示一个小例子,因为在制作中我有大量的数据。做组或使用Window函数需要很长时间。

为了做到这一点,还有其他选择吗?

1 个答案:

答案 0 :(得分:-1)

我的建议是使用reduceByKey。

这样,如果您的密钥为id且您的值(在开始时)在列表中为json_data,则执行各种{{1}的reduceByKey以及连接函数包裹列表会给你更好的表现。

简而言之,首先使用reduceByKey执行" groupBy"在分区内,然后才开始数据的混乱。

阅读groupByKey和reduceByKey的性能差异的好地方是here(部分json_data)。

在pyspark中,它将如下所示:

6b