如何在 RDD 中结转计算值? -Apache 火花
How to carry-over the calculated value within the RDD ? -Apache spark
已解决:这个问题没有好的解决办法
我确信这只是一个与语法相关的问题,而且答案很简单。
我想要实现的是:
-传递一个变量给RDD
-根据RDD数据改变变量
-获取调整后的变量
假设我有:
var b = 2
val x = sc.parallelize(0 到 3)
我想做的是获取值 2+0 + 2+0+1 + 2+0+1+2 + 2+0+1+2+3 = 18
也就是说,通过执行
之类的操作得到值 18
b = x.map(i=> … b+i…).collect
问题是,对于每个 i,我都需要携带值 b,以随着下一个 i 递增
我想使用此逻辑将元素添加到 RDD 外部的数组中
如果不先收集,我该怎么做?
如评论中所述,不可能用 RDD 的内容改变一个变量,因为 RDD 可能分布在许多不同的节点上,而可变变量对于每个执行程序 (JVM) 都是本地的。
虽然性能不是特别好,但可以通过将顺序算法转换为可在分布式环境中执行的一系列转换来在 Spark 上实现这些要求。
使用与问题相同的示例,Spark 中的该算法可以表示为:
val initialOffset = 2
val rdd = sc.parallelize(0 to 3)
val halfCartesian = rdd.cartesian(rdd).filter{case (x,y) => x>=y}
val partialSums = halfCartesian.reduceByKey(_ + _)
val adjustedPartials = partialSums.map{case (k,v) => v+initialOffset}
val total = adjustedPartials.reduce(_ + _)
scala> total
res33: Int = 18
请注意,cartesian
是一个非常昂贵的转换,因为它创建 (m x n) 个元素,或者在本例中为 n^2。
这只是说这不是不可能,但可能并不理想。
如果要顺序处理的数据量适合一台机器的内存(可能在 filtering/reduce 之后),那么 Scala 有一个内置的收集操作来准确地实现所要求的内容:scan[Left|Right]
val arr = Array(0,1,2,3)
val cummulativeScan = arr.scanLeft(initialOffset)(_ + _)
// we remove head b/c scan adds the given element at the start of the sequence
val result = cummulativeScan.tail.sum
result: Int = 18
已解决:这个问题没有好的解决办法
我确信这只是一个与语法相关的问题,而且答案很简单。
我想要实现的是:
-传递一个变量给RDD
-根据RDD数据改变变量
-获取调整后的变量
假设我有:
var b = 2
val x = sc.parallelize(0 到 3)
我想做的是获取值 2+0 + 2+0+1 + 2+0+1+2 + 2+0+1+2+3 = 18 也就是说,通过执行
之类的操作得到值 18b = x.map(i=> … b+i…).collect
问题是,对于每个 i,我都需要携带值 b,以随着下一个 i 递增
我想使用此逻辑将元素添加到 RDD 外部的数组中
如果不先收集,我该怎么做?
如评论中所述,不可能用 RDD 的内容改变一个变量,因为 RDD 可能分布在许多不同的节点上,而可变变量对于每个执行程序 (JVM) 都是本地的。
虽然性能不是特别好,但可以通过将顺序算法转换为可在分布式环境中执行的一系列转换来在 Spark 上实现这些要求。
使用与问题相同的示例,Spark 中的该算法可以表示为:
val initialOffset = 2
val rdd = sc.parallelize(0 to 3)
val halfCartesian = rdd.cartesian(rdd).filter{case (x,y) => x>=y}
val partialSums = halfCartesian.reduceByKey(_ + _)
val adjustedPartials = partialSums.map{case (k,v) => v+initialOffset}
val total = adjustedPartials.reduce(_ + _)
scala> total
res33: Int = 18
请注意,cartesian
是一个非常昂贵的转换,因为它创建 (m x n) 个元素,或者在本例中为 n^2。
这只是说这不是不可能,但可能并不理想。
如果要顺序处理的数据量适合一台机器的内存(可能在 filtering/reduce 之后),那么 Scala 有一个内置的收集操作来准确地实现所要求的内容:scan[Left|Right]
val arr = Array(0,1,2,3)
val cummulativeScan = arr.scanLeft(initialOffset)(_ + _)
// we remove head b/c scan adds the given element at the start of the sequence
val result = cummulativeScan.tail.sum
result: Int = 18