我在RDD的mapPartition中有一个double数组,当我通过这个double数组声明一个迭代器或DenseMatrix时。我发现迭代器和矩阵是空的。我的测试代码如下:
val RandXts = data.map{
line =>
val fields = patterns.findAllIn(line).toArray.map(_.toDouble)
fields(fields.length-1)
}.repartition(2)
val res = RandXts.mapPartitions(x=>{
val matrix = new DenseMatrix(x.length,1,x.toArray)
val arr = matrix.toArray
println(k.length)
(matrix::List[DenseMatrix[Double]]()).iterator
})
如上所示,行声明矩阵将导致错误。错误消息如下:
java.lang.IndexOutOfBoundsException: Storage array has size 0 but indices can grow as large as 124
如何解决此问题?
答案 0 :(得分:0)
您的代码调用x.length
,然后再次将x
传递给DenseMatrix
构造函数。由于x
是一个迭代器,因此调用length
“消耗”迭代器,因此再次传递它将导致空集合。
要解决此问题 - 扫描迭代器一次(通过将其转换为数组):
val res: RDD[DenseMatrix] = RandXts.mapPartitions(x => {
val arr = x.toArray // scan iterator only once
val matrix = new DenseMatrix(arr.length, 1, arr)
Seq(matrix).iterator // this is the return value
})
例如,对于输入val RandXts = sc.parallelize(Seq(0.5, 0.6, 0.8))
,打印结果显示它包含具有以下值的单个Matrix:
res.collect().foreach(println)
// prints:
// 0.5
// 0.6
// 0.8