如何将Spark DataFrame中的稀疏向量列转换为密集向量列?

6
我使用了以下代码:
df.withColumn("dense_vector", $"sparse_vector".toDense)  

但是它会出现一个错误。

我对Spark还很陌生,所以我的代码行可能有明显的错误。请帮忙。谢谢!

1个回答

8

需要进行此类操作的上下文在Spark中相对较少。除了一两个例外,Spark API希望使用常见的Vector类而不是特定的实现(如SparseVectorDenseVector)。对于来自o.a.s.mllib.linalg.distributed的分布式结构,也是如此。

import org.apache.spark.mllib.linalg.{Vector, Vectors}
import org.apache.spark.mllib.linalg.distributed.RowMatrix

val df = Seq[(Long, Vector)](
  (1L, Vectors.dense(1, 2, 3)), (2L, Vectors.sparse(3, Array(1), Array(3)))
).toDF("id", "v")

new RowMatrix(df.select("v")
  .map(_.getAs[Vector]("v")))
  .columnSimilarities(0.9)
  .entries
  .first
// apache.spark.mllib.linalg.distributed.MatrixEntry = MatrixEntry(0,2,1.0)

不过您可以使用这样的UDF:

但是你可以使用像这样的UDF:

val asDense = udf((v: Vector) => v.toDense)

df.withColumn("vd", asDense($"v")).show
// +---+-------------+-------------+
// | id|            v|           vd|
// +---+-------------+-------------+
// |  1|[1.0,2.0,3.0]|[1.0,2.0,3.0]|
// |  2|(3,[1],[3.0])|[0.0,3.0,0.0]|
// +---+-------------+-------------+

请记住,自2.0版本以来,Spark提供了两种不同且兼容的Vector类型:

  • o.a.s.ml.linalg.Vector
  • o.a.s.mllib.linalg.Vector

每个都有相应的SQL UDT。请参见MatchError while accessing vector column in Spark 2.0


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接