Spark Scala汇总数据集的列元素?

Spark Scala汇总数据集的列元素?,scala,count,apache-spark,Scala,Count,Apache Spark,我需要计算值示例“2”在每列中出现的次数 我的数据集具有以下结构: 1 1 2 0 0 0 2 0 2 0 1 1 1 1 1 2 1 0 2 2 2 0 0 0 0 1 1 2 我导入了该文件: val ip = sc.textFile("/home/../data-scala.txt").map(line => line.split(" ")) 如何将每列中等于“2”的值相加?我希望有一个数组的元素作为结果 [0,2,1,0,1,1,3] 你可以先在每个位置映射2的存在,给你

我需要计算值示例“2”在每列中出现的次数

我的数据集具有以下结构:

1 1 2 0 0 0 2 
0 2 0 1 1 1 1
1 2 1 0 2 2 2
0 0 0 0 1 1 2
我导入了该文件:

val ip = sc.textFile("/home/../data-scala.txt").map(line => line.split(" "))
如何将每列中等于“2”的值相加?我希望有一个数组的元素作为结果

[0,2,1,0,1,1,3]

你可以先在每个位置
映射
2
的存在,给你

[ 0 0 1 0 0 0 1 ]
[ 0 1 0 0 0 0 0 ]
[ 0 1 0 0 1 1 1 ]
[ 0 0 0 0 0 0 1 ]
然后做一个reduce,逐步求和每一列

在不涉及Spark的情况下,它看起来像:

val list = Seq(
  Seq(1, 1, 2, 0, 0, 0, 2),
  Seq(0, 2, 0, 1, 1, 1, 1),
  Seq(1, 2, 1, 0, 2, 2, 2),
  Seq(0, 0, 0, 0, 1, 1, 2)
)

list.
   map(_.map(v => if(v == 2) 1 else 0)).
   reduce((a,b) => a.zip(b).map(t => t._1 +t._2 ))

找到这种单衬套的最佳版本可能有点像是一项代码高尔夫挑战。

像这样的东西怎么样:

import breeze.linalg.DenseVector

def toInd(s: String): DenseVector[Int] = {
    DenseVector[Int](s.split(" ").map(x => if(x == "2") 1 else 0))
}

sc.textFile("/path/to/file").map(toInd).reduce(_ + _)
如果希望有大量列的和等于零,则可以将
DenseVector
替换为
SparseVector

上述解决方案要求RDD的每个元素都有一个新的
DenseVector
对象。出于性能原因,您可以考虑使用<代码>聚合< /代码>和向量突变:

def seqOp(acc: DenseVector[Int] , cols: Array[String]): DenseVector[Int] = {
    cols.zipWithIndex.foreach{ case (x, i) => if(x == "2") acc(i) += 1}
    acc
}

def combOp(acc1: DenseVector[Int], acc2: DenseVector[Int]): DenseVector[Int] = {
    acc1 += acc2
    acc1
}

val n = ip.first.length
ip.aggregate(DenseVector.zeros[Int](n))(seqOp, combOp)
如果需要,您可以轻松地将
DenseVector
替换为稀疏的或
scala.collection.mutable.Map


如果你问我这是相当丑陋的,所以我提供它只是为了让一个完整的答案

这就是你想要你的答案[0,2,1,0,1,1,3]?你可以用你的RDD,然后用
transposedRdd.map(u.count(==“2”))来计算
2
s(uuu.count(==“2”)
@peterneens Transposition是昂贵的,并不总是可行的,这里真的没有必要。是的,我想得到一个数组,其中包含的计数和为[0,2,1,1,3]我导入的文件保存为数组[Array[String]]