代码之家  ›  专栏  ›  技术社区  ›  kingledion

如何将一列或一系列向量转换成稀疏矩阵?

  •  0
  • kingledion  · 技术社区  · 6 年前

    正如标题所说,我有一个向量序列(在DataFrame列中,但可以使用.collect()将其转换为RDD或序列)。我想把这些向量收集到一个局部稀疏矩阵中。为了与Spark 1.6.3兼容,我需要它是的mllib版本 SparseMatrix .

    作为一个序列的sparsevector收集,我得到

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

    我可以很容易地制作一个行矩阵,但是我也看不到任何将行矩阵转换为局部矩阵的方法。

    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 回复  |  直到 6 年前
        1
  •  0
  •   kingledion    6 年前

    给定一系列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 SparseMatrix . 行数是传递的向量数;列数是最长SparseVector的长度:

    SparseMatrix.fromCOO(seq_of_vectors.length,
        seq_of_vectors.map(_.size).max,
        coo)
    
    res223: org.apache.spark.mllib.linalg.SparseMatrix = 
    84 x 262144 CSCMatrix
    ...
    (28,136034) 0.8164965809277259
    ...
    (28,155107) 0.40824829046386296
    ...
    (28,166596) 0.40824829046386296
    ...