使用ReduceByKey来对值列表进行分组

11 浏览
0 Comments

使用ReduceByKey来对值列表进行分组

我想按键对值进行分组,之前我是这样做的:

sc.parallelize(Array(("red", "zero"), ("yellow", "one"), ("red", "two"))).groupByKey().collect.foreach(println)
(red,CompactBuffer(zero, two))
(yellow,CompactBuffer(one))

但我注意到Databricks的一篇博客文章,它建议不要在大型数据集中使用groupByKey。

避免使用GroupByKey

有没有办法使用reduceByKey实现相同的结果?

我尝试了以下方法,但它会将所有的值连接在一起。顺便说一下,对于我的情况,键和值都是字符串类型的。

sc.parallelize(Array(("red", "zero"), ("yellow", "one"), ("red", "two"))).reduceByKey(_ ++ _).collect.foreach(println)
(red,zerotwo)
(yellow,one)

0
0 Comments

使用reduceByKey来分组值列表的问题是:它不提供比groupByKey更好的性能,并且由于对GC的压力较大,实际上效率显著低下。

解决方法是:使用aggregateByKey。以下是使用aggregateByKey解决该问题的代码示例:

 sc.parallelize(Array(("red", "zero"), ("yellow", "one"), ("red", "two")))
.aggregateByKey(ListBuffer.empty[String])(
        (numList, num) => {numList += num; numList},
         (numList1, numList2) => {numList1.appendAll(numList2); numList1})
.mapValues(_.toList)
.collect()
scala> Array[(String, List[String])] = Array((yellow,List(one)), (red,List(zero, two)))

关于aggregateByKey的详细信息,请参见此答案,关于使用可变数据集ListBuffer的原因,请参见此链接

reduceByKey的上述方法实际上性能更差,请参见上述链接中的评论。它与groupByKey相比没有提供任何性能改进。由于对GC的压力较大,它实际上效率显著低下。

当前实现中,如果您确实需要按键进行分组,那么groupByKey是您能得到的最好的结果。还有其他方法(例如外部排序),但这些方法不会产生相同的结构。

以上是关于使用reduceByKey进行分组值列表的问题的原因和解决方法的总结。

0
0 Comments

使用reduceByKey对值列表进行分组的原因是,我们有一个包含键值对的RDD,其中每个键都对应一个值列表。我们想要将具有相同键的所有值列表合并为一个值列表。

解决方法是使用reduceByKey函数,它将具有相同键的值列表合并为一个值列表。在给定的示例中,我们首先使用map函数将每个值转换为一个列表,然后使用reduceByKey函数将具有相同键的所有值列表合并为一个值列表。

具体来说,我们首先使用parallelize函数创建一个包含键值对的RDD。然后,我们使用map函数将每个值转换为一个列表。接下来,我们使用reduceByKey函数将具有相同键的所有值列表合并为一个值列表。最后,我们使用collect函数将结果收集到本地驱动程序。

最终的结果是一个包含键值对的数组,其中每个键都对应一个值列表。在给定的示例中,结果是Array((red,List(zero, two)), (yellow,List(one)))。这意味着键"red"对应的值列表是["zero", "two"],键"yellow"对应的值列表是["one"]。

使用reduceByKey函数对值列表进行分组是一种常见的操作,可以用于各种情况,例如在处理数据时将具有相同键的值合并为一个值。

0