我想将两个源自文本文件的稀疏矩阵相乘。我目前有这个代码:
import org.apache.spark.SparkContext
import org.apache.spark.SparkConf
@SerialVersionUID(123L)
case class M_Matrix ( i: Long, j: Long, v: Double )
extends Serializable {}
@SerialVersionUID(123L)
case class N_Matrix ( j: Long, k: Long, w: Double )
extends Serializable {}
object Multiply {
def main(args: Array[ String ]){
val conf = new SparkConf().setAppName("Multiply")
val sc = new SparkContext(conf)
val M_ = sc.textFile(args(0)).map( line => { val a = line.split(",")
M_Matrix(a(0).toLong,a(1).toLong,a(2).toDouble) } )
val N_ = sc.textFile(args(1)).map( line => { val a = line.split(",")
N_Matrix(a(0).toLong, a(1).toLong, a(2).toDouble) } )
val res = M_.map( M_ => (M_.j,M_) )
.join(N_.map( N_ => (N_.j, N_)))
.map({case (j, ((i,v),(k,w))) => ((i,k), v * w)})
.reduceByKey(_ + _)
.map({ case ((i,k), sum) => (i, k, sum)} )
res.saveAsTextFile(args(2))
sc.stop()
}
}
它给了我一个错误* *在v * w中不是有效的运算符。
我做错了什么?
答案 0 :(得分:0)
代码几乎是正确的,需要进行一些小的更改才能使其正常工作。具体而言,在map
操作之前的矩阵join
中完成:
M_.map( M_ => (M_.j, (M_.i, M_.v))).join(N_.map(N_ => (N_.j, (N_.k, N_.w))))
元组应该在这里用作值,因为在下一个语句中元组是预期的,
.map{ case(j, ((i,v),(k,w))) => ((i,k), v * w)}
我建议尝试使用Spark中的内置功能,因为它应该更高效。可以从RDD[MatrixEntry]
创建矩阵。首先创建两个矩阵:
import org.apache.spark.mllib.linalg.distributed.{BlockMatrix, CoordinateMatrix, MatrixEntry}
val M_ = sc.textFile(args(0)).map{ line =>
val a = line.split(",")
MatrixEntry(a(0).toLong, a(1).toLong, a(2).toDouble)
}
val N_ = sc.textFile(args(1)).map{ line =>
val a = line.split(",")
MatrixEntry(a(0).toLong, a(1).toLong, a(2).toDouble)
}
然后将它们转换为BlockMatrix
:
val matrix_M = new CoordinateMatrix(M_).toBlockMatrix()
val matrix_N = new CoordinateMatrix(N_).toBlockMatrix()
之后,您可以使用函数multiply
简单地将它们相乘:
val res = matrix_M.multiply(matrix_N)