将RDD转换为PairRDD

3

这是一个新手问题。

是否有可能将具有动态维度的RDD(如(key,1,2,3,4,5,5,666,789,...))转换为像(key, (1,2,3,4,5,5,666,789,...))这样的pairRDD?

我觉得这应该非常容易,但我不知道怎么做。

这样做的目的是我想对所有值进行求和,但不包括键。

感谢任何帮助。

我正在使用Spark 1.2.0

编辑:受答案启发,我更深入地解释了我的用例。 我有N个(在编译时未知)不同的pairRDD(key,value),必须加入并对其值求和。 是否有比我考虑的更好的方法?


目前它们只是整数,我正在考虑将它们收集在一个元组中,是的,除非你有更好的想法。我愿意讨论。 - Irene
我想要获取一个pairRDD,其中第一个元素是起始RDD的第一个元素,第二个元素是一个元组,包含了原始RDD中除第一个元素外的所有内容。现在是否更清晰了? - Irene
1
是的,但这不可行。如果这样做,您将在一个节点上收集除一个元素之外的所有rdd元素。如果您的rdd很大,它可能会因缺乏内存而崩溃。 - abalcerek
从RDD中获取第一个元素并不容易。您可以通过阅读此链接来了解其背后的原理:https://dev59.com/Z18d5IYBdhLWcg3wchyi。这将为您提供有关如何继续操作的提示。 - Carlos Vilchez
@Irene 原始RDD的类型是什么? - Shyamendra Solanki
显示剩余4条评论
1个回答

2

首先,如果您想简单地对除第一个以外的所有整数求和,最简单的方法是:

val rdd = sc.parallelize(List(1, 2, 3))
rdd.cache()
val first = rdd.sum()
val result = rdd.count - first

另一方面,如果您想访问元素的索引,可以使用rdd zipWithIndex方法,如下所示:

  val indexed = rdd.zipWithIndex()
  indexed.cache()
  val result = (indexed.first()._2, indexed.filter(_._1 != 1))

但在你的情况下,这似乎有点过头了。

我想补充一件事,这看起来像是一个可疑的设计,将关键字作为rdd的第一个元素。为什么不在驱动程序中使用成对的(key, rdd)呢?很难推断出rdd中元素的顺序,我不能不考虑到当关键字被计算为rdd的第一个元素时的自然情况(当然,我不知道你的用例,所以我只能猜测)。

编辑

如果你有一个键值对的rdd,并且想按键值进行求和,则只需执行以下操作:

val result = rdd.reduceByKey(_ + _)

如果在计数之前有许多键值对的RDD,您只需将它们加起来即可。
  val list = List(pairRDD0, pairRDD1, pairRDD2)
  //another pairRDD arives in runtime
  val newList = anotherPairRDD0::list
  val pairRDD = newList.reduce(_ union _)
  val resultSoFar = pairRDD.reduceByKey(_ + _)
  //another pairRDD arives in runtime
  val result = resultSoFar.union(anotherPairRDD1).reduceByKey(_ + _)

编辑

我编辑了一个示例。正如您所看到的,当每次在运行时出现时,您可以添加额外的rdd。这是因为reduceByKey返回相同类型的rdd,因此您可以迭代此操作(当然,您需要考虑性能)。


谢谢您的帮助。根据您的解释,我编辑了问题,您有更好的建议吗? - Irene
你的回答非常有帮助,但问题在于我不知道编译时配对RDD的数量,因此无法像你那样编写val列表。有没有什么方法可以解决这个问题? - Irene

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