我有一个带有下一个信息的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函数需要很长时间。
为了做到这一点,还有其他选择吗?
答案 0 :(得分:-1)
我的建议是使用reduceByKey。
这样,如果您的密钥为id
且您的值(在开始时)在列表中为json_data
,则执行各种{{1}的reduceByKey以及连接函数包裹列表会给你更好的表现。
简而言之,首先使用reduceByKey执行" groupBy"在分区内,然后才开始数据的混乱。
阅读groupByKey和reduceByKey的性能差异的好地方是here(部分json_data
)。
在pyspark中,它将如下所示:
6b