无法将 Spark ML 库中的 Vector 用于 DataFrame

Posted

技术标签:

【中文标题】无法将 Spark ML 库中的 Vector 用于 DataFrame【英文标题】:Can't use Vector from Spark ML Lib for the DataFrame 【发布时间】:2015-10-07 15:16:59 【问题描述】:

当我尝试使用返回 Vector 对象的 UDF 时,Spark 抛出以下异常:

Cause: java.lang.UnsupportedOperationException: Not supported DataType: org.apache.spark.mllib.linalg.VectorUDT@f71b0bce

如何在我的 UDF 中使用 Vector? Spark 版本是 1.5.1。

UPD

val dataFrame: DataFrame = sqlContext.createDataFrame(Seq(
  (0, 1, 2),
  (0, 3, 4),
  (0, 5, 6)
)).toDF("key", "a", "b")

val someUdf = udf 
  (a: Double, b: Double) => Vectors.dense(a, b)


dataFrame.groupBy(col("key"))
  .agg(someUdf(avg("a"), avg("b")))

【问题讨论】:

【参考方案1】:

您的 UDF 本身没有任何问题。看起来您遇到了异常,因为您在聚合列上的 agg 方法中调用了它。要使其正常工作,您只需将其推到agg 步骤之外:

dataFrame
  .groupBy($"key")
  .agg(avg($"a").alias("a"), avg($"b").alias("b"))
  .select($"key", someUdf($"a", $"b"))

【讨论】:

感谢您的回复。如果我将 Vectors.dense() 更改为 Array(),则相同的代码有效。 我知道。看起来问题是特定于 aggVectorUDT 计算列的组合。 你的例子对我有用。再次感谢。但我认为这种行为很奇怪。如果我使用一些原始类型或即ArraysomeUdfagg 方法中效果很好。有人可以解释为什么会这样吗? Vector 的问题在于它不是原生 Spark SQL 类型。它被实现为具有相当复杂表示的用户定义类型(因此VectorUDT)。我想有人没有预测到这样的用例:)我仍然不得不承认这令人困惑。

以上是关于无法将 Spark ML 库中的 Vector 用于 DataFrame的主要内容,如果未能解决你的问题,请参考以下文章

值 toDF 不是 org.apache.spark.rdd.RDD[(Long, org.apache.spark.ml.linalg.Vector)] 的成员

如何在 Apache Spark ML API 中从“DataFrame”创建一个“Vector”?

使用 Spark ML 时出现 VectorUDT 问题

Spark机器学习中ml和mllib中矩阵向量

将包含 Vector 作为特征的 Spark 数据帧转换为 CSV 文件

PySpark ML——分布式机器学习库