Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/scala/18.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/apache-spark/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
构建稀疏矩阵scala-spark_Scala_Apache Spark - Fatal编程技术网

构建稀疏矩阵scala-spark

构建稀疏矩阵scala-spark,scala,apache-spark,Scala,Apache Spark,我有一个表单的输入文件 (id | column_name | value) ... 列名称可以有大约50个名称,ID列表可能非常庞大 我想构建一个又高又瘦的矩阵,其(I,j)系数对应于(id,column_name)处的值,id映射到I,column name映射到j 到目前为止,我的方法如下 我加载文件 val f = sc.textFile("example.txt") val data = f.map(_.split('|') match { case Arr

我有一个表单的输入文件

(id | column_name | value)
...
列名称可以有大约50个名称,ID列表可能非常庞大

我想构建一个又高又瘦的矩阵,其(I,j)系数对应于(id,column_name)处的值,id映射到I,column name映射到j

到目前为止,我的方法如下

我加载文件

val f = sc.textFile("example.txt") 
    val data = f.map(_.split('|') match {
        case Array(id, column_name, score) =>
        (id.toInt, column_name.toString, score.toDouble)
        }
    )
然后我将构建列名称和ID列表

    val column_name_list = data.map(x=>(x._2)._1).distinct.collect.zipWithIndex
    val ids_list = data.map(x=>x._1).distinct.collect.zipWithIndex
    val nCols = column_name_list.length
    val nRows = ids_list.length
然后我将构建一个坐标矩阵,使用我刚刚创建的映射定义条目

    val broadcastcolumn_name = sc.broadcast(column_name_list.toMap)
    val broadcastIds = sc.broadcast(ids_list.toMap)

    val matrix_entries_tmp = data.map{
            case(id, column_name, score) => (broadcastIds.value.getOrElse(id,0), broadcastcolumn_name.value.getOrElse(column_name,0), score)
    }   

    val matrix_entries = matrix_entries_tmp.map{
            e => MatrixEntry(e._1, e._2, e._3)
    }   

    val coo_matrix = new CoordinateMatrix(matrix_entries)
这项工作在小例子上做得很好。但是,当id列表越来越大时,我得到了一个内存错误。问题似乎是:

val ids_list = data.map(x=>x._1).distinct.collect.zipWithIndex
这会导致内存错误

解决办法是什么?实际上我并不需要id映射。重要的是列名以及每一行对应于某个(丢失的)id。我曾考虑使用IndexedRowMatrix,但我一直在思考如何使用它

谢谢你的帮助

坐标矩阵 太难看了,这不是一个像样的解决方案,但它应该给你一些开始的地方

首先,让我们创建列名和索引之间的映射:

val colIdxMap = sc.broadcast(data.
     map({ case (row, col, value) => col }).
     distinct.
     zipWithIndex.
     collectAsMap)
按行id对列进行分组,并将值映射到对
(colIdx,value)

生成条目:

val entries = values.
     zipWithIndex.
     flatMap { case (vals, row) =>
         vals.map {case (col, value) => MatrixEntry(row, col, value)}
     }
创建最终矩阵:

val mat: CoordinateMatrix = new CoordinateMatrix(entries)
行矩阵 如果行ID根本不重要,您可以使用
行矩阵
,如下所示:

首先让我们按行分组数据

val dataByRow = data.groupBy { case (row, col, value) => row }
为每行生成稀疏向量:

val rows = dataByRow.mapValues((vals) => {
    val cols = vals.map {
        case (_, col, value) => (colIdxMap.value(col).toInt, value)
    }
    Vectors.sparse(colIdxMap.value.size, cols.toSeq)
}).values
创建一个矩阵:

val mat: RowMatrix = new RowMatrix(rows)
您可以在
行上使用
zipWithIndex
来创建
RDD[IndexedRow]
IndexedRowMatrix

val mat: RowMatrix = new RowMatrix(rows)