繁体   English   中英

在Scala中汇总Spark数据集的问题

[英]Issues Aggregating Spark Datasets in Scala

我正在使用scala的/:运算符计算一系列数据集聚合。 汇总的代码如下:

def execute1( 
xy: DATASET, 
f: Double => Double): Double = {

println("PRINTING: The data points being evaluated: " + xy)
println("PRINTING: Running execute1")

var z = xy.filter{ case(x, y) => abs(y) > EPS}

var ret = - z./:(0.0) { case(s, (x, y)) => {
   var px = f(x)
   s + px*log(px/y)}  
}

ret
}

当我尝试运行作为f参数传入的单独函数列表的块时,会发生我的问题。 功能列表是:

  lazy val pdfs = Map[Int, Double => Double](
1 -> betaScaled,
2 -> gammaScaled,
3 -> logNormal,
4 -> uniform,
5 -> chiSquaredScaled
)

通过列表运行聚合的执行程序函数是:

  def execute2( 
xy: DATASET, 
fs: Iterable[Double=>Double]): Iterable[Double] = { 
fs.map(execute1(xy, _))
}

在最终执行块中:

val kl_rdd  = master_ds.mapPartitions((it:DATASET) => {
val pdfsList = pdfs_broadcast.value.map(
     n => pdfs.get(n).get
)

execute2(it, pdfsList).iterator

问题是,尽管确实发生了聚合,但当我希望每个函数的聚合分别显示时,它们似乎都在输出数组的第一个插槽中聚合了。 我进行了测试,以确认所有五个功能实际上都在运行,并且已在第一个插槽中对它们进行了求和。

The pre-divergence value: -4.999635700491883
The pre-divergence value: -0.0
The pre-divergence value: -0.0
The pre-divergence value: -0.0
The pre-divergence value: -0.0

这是我遇到过的最困难的问题之一,因此任何方向都将不胜感激。 将给予应有的信誉。 谢谢!

斯巴克的数据集没有foldLeft (又名/: https://spark.apache.org/docs/2.1.0/api/scala/index.html#org.apache.spark.sql.Dataset和实际需要类型参数DataSet[T]及其名称并非全大写。

因此,我想您的DATASET的类型是一个迭代器,因此它在第一次运行execute1 execute1被清空,因此每个后续的execute1execute1空迭代器。 基本上,它不会聚合所有函数-它仅执行第一个函数,而忽略其他函数(由于将0.0作为初始值传递给foldLeft,因此得到-0.0)。

mapPartitions签名可以看到:

def mapPartitions[U](f: (Iterator[T]) ⇒ Iterator[U], preservesPartitioning: Boolean = false)(implicit arg0: ClassTag[U]): RDD[U]

它为您提供了一个迭代器(只能遍历一次的可变结构),因此您应该执行it.toList以获取(可能但有限的大型)不可变结构( List )。

PS,如果您想真正使用Spark的DataSet / RDD,请使用aggregate (RDD)或agg (DataSet)。 另请参见: 在Spark中是否等于foldLeft或foldRight?


有关迭代器的说明:

scala> val it = List(1,2,3).toIterator
it: Iterator[Int] = non-empty iterator

scala> it.toList //traverse iterator and accumulate its data into List
res0: List[Int] = List(1, 2, 3)

scala> it.toList //iterator is drained, so second call doesn't traverse anything
res1: List[Int] = List()

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM