我有一个具有以下格式(id,f1,f2,f3,...,fn
)的文本文件:
12345,0,0,1,2,...,3
23456,0,0,1,2,...,0
33333,0,1,1,0,...,0
56789,1,0,0,0,...,4
a_123,0,0,0,6,...,3
我想读取文件(忽略像a_123,0,0,0,6,...,3
这样的行)来创建RDD[(Long, Vector)
。这是我的解决方案:
def readDataset(path: String, sparkSession: SparkSession): RDD[(ItemId, Vector)] = {
val sc = sparkSession.sparkContext
sc.textFile(path)
.map({ line => val values=line.split(",")
(
values(0).toLong,
//util.Try(values(0).toLong).getOrElse(0L),
Vectors.dense(values.slice(1, values.length).map {x => x.toDouble }).toSparse
)})
.filter(x => x._1 > 0)
}
但是此代码无法编译:
[ERROR] found : org.apache.spark.rdd.RDD[(Long, org.apache.spark.ml.linalg.SparseVector)]
[ERROR] required: org.apache.spark.rdd.RDD[(Long, org.apache.spark.ml.linalg.Vector)]
[ERROR] (which expands to) org.apache.spark.rdd.RDD[(Long, org.apache.spark.ml.linalg.Vector)]
[ERROR] Note: (Long, org.apache.spark.ml.linalg.SparseVector) <: (Long, org.apache.spark.ml.linalg.Vector), but class RDD is invariant in type T.
[ERROR] You may wish to define T as +T instead. (SLS 4.5)
[ERROR] .filter(x => x._1 > 0)
[ERROR] ^
[ERROR] one error found
但是,如果我删除了. toSparse
或.filter(x => x._1 > 0)
,则此代码可以成功编译。
有人知道为什么以及应该怎么解决吗?
还有没有更好的方法可以忽略非数字ID行将文件读取到RDD?
答案 0 :(得分:0)
如果您删除toSparse
,因为您的PairRDD
的类型是(ItemId, Vector)
,则代码可以成功编译。
org.apache.spark.ml.linalg.Vector
类/类型表示您使用Vector.dense
生成的密集向量,当您调用toSparse
时,它将转换为org.apache.spark.ml.linalg.SparseVector
,而不是该类型。您的PairRDD期望的。
对于过滤非整数ID,我想说您的方法是一种很好的方法。