Невозможно использовать вектор из Spark ML Lib для DataFrame

Когда я пытаюсь использовать UDF, который возвращает объект Vector, Spark выдает следующее исключение:

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

Как я могу использовать 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")))

person Zyoma    schedule 07.10.2015    source источник


Ответы (1)


Нет ничего плохого в вашем UDF как таковом. Похоже, вы получаете исключение, потому что вызываете его внутри метода agg для агрегированных столбцов. Чтобы заставить его работать, вы можете просто вытолкнуть его за пределы шага agg:

dataFrame
  .groupBy($"key")
  .agg(avg($"a").alias("a"), avg($"b").alias("b"))
  .select($"key", someUdf($"a", $"b"))
person zero323    schedule 07.10.2015
comment
Спасибо за ваш ответ. Тот же код работает, если я изменю Vectors.dense() на i.e. Array(). - person Zyoma; 07.10.2015
comment
Я знаю. Похоже, проблема связана с комбинацией вычисляемых столбцов agg и VectorUDT. - person zero323; 07.10.2015
comment
Ваш пример работает для меня. Спасибо еще раз. Но я считаю такое поведение странным. someUdf хорошо работает в методе agg, если я использую какой-то примитивный тип или, например, Array. Может кто-нибудь объяснить, почему это происходит? - person Zyoma; 07.10.2015
comment
Проблема с Vector заключается в том, что это не собственный тип Spark SQL. Он реализован как определяемый пользователем тип (отсюда VectorUDT) с довольно сложным представлением. Я думаю, что кто-то не предсказал такой вариант использования :) Тем не менее, я должен признать, что это сбивает с толку. - person zero323; 07.10.2015