如何将向量的列或序列转换为SparseMatrix?

时间:2018-09-10 20:02:56

标签: scala apache-spark matrix sparse-matrix

正如标题所述,我有一个向量序列(在DataFrame列中,但是可以将其转换为RDD或使用.collect()的序列)。我想将这些向量收集到本地SparseMatrix中。为了与Spark 1.6.3具有向后兼容性,我需要将其作为SparseMatrix的mllib版本。

我将其收集为一系列稀疏向量,

val seq_of_vectors = df_with_vectors.select("sparse").map(_.getAs[SparseVector](0)).collect()
seq_of_vectors: Array[org.apache.spark.mllib.linalg.SparseVector] = ...

我可以轻松地制作RowMatrix,但是我也看不到将RowMatrix转换为本地矩阵的任何方法。

val exampleMatrix = new RowMatrix(df_with_vectors.select("sparse").rdd.map(_.getAs[SparseVector](0)))
exampleMatrix: org.apache.spark.mllib.linalg.distributed.RowMatrix = org.apache.spark.mllib.linalg.distributed.RowMatrix@2e6273dc

1 个答案:

答案 0 :(得分:0)

给出序列形式的SparseVector对象

seq_of_vectors: Array[org.apache.spark.mllib.linalg.SparseVector] = 
    Array(..., (262144,[136034,155107,166596],[0.8164965809277259,0.40824829046386296,0.40824829046386296]), ...

我们使用以下命令将其转换为(行,列,值)的坐标列表元组:

val coo = (seq_of_vectors.map(_.numNonzeros).zipWithIndex.flatMap{case (cnt, idx) => Array.fill(cnt)(idx) },
    seq_of_vectors.map(_.indices).flatten,
    seq_of_vectors.map(_.values).flatten
).zipped.toArray

coo: Array[(Int, Int, Double)] = 
    Array( ..., (28,136034,0.8164965809277259), (28,155107,0.40824829046386296), (28,166596,0.40824829046386296), ...

然后,我们使用fromCOO的{​​{1}}函数。行数是传递的向量数。而列数是最长SparseVector的长度:

SparseMatrix