Spark 数据帧到空的稀疏向量
Spark dataframe to sparse vector with null
当我尝试在 Scala 中 assemble 一个向量形成一个数据框(一些列包含 null
值)时,我遇到了一个问题。不幸的是 vectorAssembler
无法处理 null
个值。
我能做的是替换或填充数据框的 null
值,然后创建一个 dense
向量,但这不是我想要的。
所以我考虑将我的数据帧行转换为 sparse
向量。但是我怎样才能做到这一点?我还没有找到 vectorAssembler
制作稀疏向量的选项。
编辑:实际上我不需要 null
在稀疏向量中,但它不应该是像 0
或任何其他值,因为它是密集向量的情况。
你有什么建议吗?
您可以像这样手动完成:
import org.apache.spark.SparkException
import org.apache.spark.ml.linalg.{Vector, Vectors}
import org.apache.spark.sql.SparkSession
import scala.collection.mutable.ArrayBuilder
case class Row(a: Double, b: Option[Double], c: Double, d: Vector, e: Double)
val dataset = spark.createDataFrame(
Seq(new Row(0, None, 3.0, Vectors.dense(4.0, 5.0, 0.5), 7.0),
new Row(1, Some(2.0), 3.0, Vectors.dense(4.0, 5.0, 0.5), 7.0))
).toDF("id", "hour", "mobile", "userFeatures", "clicked")
val sparseVectorRDD = dataset.rdd.map { row =>
val indices = ArrayBuilder.make[Int]
val values = ArrayBuilder.make[Double]
var cur = 0
row.toSeq.foreach {
case v: Double =>
indices += cur
values += v
cur += 1
case vec: Vector =>
vec.foreachActive { case (i, v) =>
indices += cur + i
values += v
}
cur += vec.size
case null =>
cur += 1
case o =>
throw new SparkException(s"$o of type ${o.getClass.getName} is not supported.")
}
Vectors.sparse(cur, indices.result(), values.result())
}
然后根据需要将其转换回数据框。由于 Row 对象未进行类型检查,因此您必须手动处理它并在需要时转换为适当的类型。
当我尝试在 Scala 中 assemble 一个向量形成一个数据框(一些列包含 null
值)时,我遇到了一个问题。不幸的是 vectorAssembler
无法处理 null
个值。
我能做的是替换或填充数据框的 null
值,然后创建一个 dense
向量,但这不是我想要的。
所以我考虑将我的数据帧行转换为 sparse
向量。但是我怎样才能做到这一点?我还没有找到 vectorAssembler
制作稀疏向量的选项。
编辑:实际上我不需要 null
在稀疏向量中,但它不应该是像 0
或任何其他值,因为它是密集向量的情况。
你有什么建议吗?
您可以像这样手动完成:
import org.apache.spark.SparkException
import org.apache.spark.ml.linalg.{Vector, Vectors}
import org.apache.spark.sql.SparkSession
import scala.collection.mutable.ArrayBuilder
case class Row(a: Double, b: Option[Double], c: Double, d: Vector, e: Double)
val dataset = spark.createDataFrame(
Seq(new Row(0, None, 3.0, Vectors.dense(4.0, 5.0, 0.5), 7.0),
new Row(1, Some(2.0), 3.0, Vectors.dense(4.0, 5.0, 0.5), 7.0))
).toDF("id", "hour", "mobile", "userFeatures", "clicked")
val sparseVectorRDD = dataset.rdd.map { row =>
val indices = ArrayBuilder.make[Int]
val values = ArrayBuilder.make[Double]
var cur = 0
row.toSeq.foreach {
case v: Double =>
indices += cur
values += v
cur += 1
case vec: Vector =>
vec.foreachActive { case (i, v) =>
indices += cur + i
values += v
}
cur += vec.size
case null =>
cur += 1
case o =>
throw new SparkException(s"$o of type ${o.getClass.getName} is not supported.")
}
Vectors.sparse(cur, indices.result(), values.result())
}
然后根据需要将其转换回数据框。由于 Row 对象未进行类型检查,因此您必须手动处理它并在需要时转换为适当的类型。