У меня есть фрейм данных doubleSeq, структура которого приведена ниже.
res274: org.apache.spark.sql.DataFrame = [finalFeatures: vector]
Первая запись столбца выглядит следующим образом
res281: org.apache.spark.sql.Row = [[3.0,6.0,-0.7876947819954485,-0.21757635218517163,0.9731844373162398,-0.6641741696340383,-0.6860072219935377,-0.2990737363481845,-0.7075863760365155,0.8188108975549018,-0.8468559840943759,-0.04349947247406488,-0.45236764452589984,1.0333959313820456,0.6097566070878347,-0.7106619551471779,-0.7750330808435969,-0.08097610412658443,-0.45338437108038904,-0.2952869863393396,-0.30959772365257004,0.6988768123463287,0.17049117199049213,3.2674649019757385,-0.8333373234944124,1.8462942520757128,-0.49441222531240125,-0.44187299748074166,-0.300810826687287]]
Я хочу извлечь двойной массив
[3.0,6.0,-0.7876947819954485,-0.21757635218517163,0.9731844373162398,-0.6641741696340383,-0.6860072219935377,-0.2990737363481845,-0.7075863760365155,0.8188108975549018,-0.8468559840943759,-0.04349947247406488,-0.45236764452589984,1.0333959313820456,0.6097566070878347,-0.7106619551471779,-0.7750330808435969,-0.08097610412658443,-0.45338437108038904,-0.2952869863393396,-0.30959772365257004,0.6988768123463287,0.17049117199049213,3.2674649019757385,-0.8333373234944124,1.8462942520757128,-0.49441222531240125,-0.44187299748074166,-0.300810826687287]
из этого -
doubleSeq.head(1)(0)(0)
дает
Any = [3.0,6.0,-0.7876947819954485,-0.21757635218517163,0.9731844373162398,-0.6641741696340383,-0.6860072219935377,-0.2990737363481845,-0.7075863760365155,0.8188108975549018,-0.8468559840943759,-0.04349947247406488,-0.45236764452589984,1.0333959313820456,0.6097566070878347,-0.7106619551471779,-0.7750330808435969,-0.08097610412658443,-0.45338437108038904,-0.2952869863393396,-0.30959772365257004,0.6988768123463287,0.17049117199049213,3.2674649019757385,-0.8333373234944124,1.8462942520757128,-0.49441222531240125,-0.44187299748074166,-0.300810826687287]
Что не решает мою проблему
Scala Spark - разделить векторный столбец на отдельные столбцы в Spark DataFrame
Не решает мою проблему, но это показатель
Итак, вы хотите извлечь вектор из строки и превратить его в массив двойников.
Проблема с вашим кодом заключается в том, что метод get
(и неявный метод apply
, который вы используете) возвращает объект типа Any
. Действительно, Row
— это общий, непараметризованный объект, и теперь во время компиляции нет возможности узнать, какие типы он содержит. Это немного похоже на списки в java 1.4 и более ранних версиях. Чтобы решить это в искре, вы можете использовать метод getAs
, который вы можете параметризовать с помощью выбранного вами типа.
В вашей ситуации у вас, кажется, есть фрейм данных, содержащий вектор (org.apache.spark.ml.linalg.Vector
).
import org.apache.spark.ml.linalg._
val firstRow = df.head(1)(0) // or simply df.head
val vect : Vector = firstRow.getAs[Vector](0)
// or all in one: df.head.getAs[Vector](0)
// to transform into a regular array
val array : Array[Double] = vect.toArray
Также обратите внимание, что вы можете получить доступ к столбцам по имени следующим образом:
val vect : Vector = firstRow.getAs[Vector]("finalFeatures")
.toArray
, я отредактировал ответ, чтобы сделать его более понятным.
значение getAs не является членом org.apache.spark.sql.DataFrame -> какой оператор импорта вы используете?
Это метод Row, а не dataframe
Я получаю сообщение об ошибке: java.lang.ClassCastException: org.apache.spark.ml.linalg.DenseVector не может быть приведен к scala.collection.Seq... 54 исключено
Ошибка для этого кода: import org.apache.spark.mllib.linalg.Vectors result.select("finalFeatures").head(1)(0).getAs[Seq[Double]](0)
О, я вижу. Можете ли вы дать мне результат dataframe.printSchema
?
root |-- finalFeatures: вектор (nullable = true)
Я отредактировал свой ответ, чтобы учесть все это. Теперь должно работать нормально ;)
java.lang.ClassCastException: org.apache.spark.ml.linalg.DenseVector не может быть приведен к org.apache.spark.mllib.linalg.Vector... 76 пропущено... извините, я получаю эту ошибку... есть два ошибки здесь?
попробуйте getAs[DenseVector]
тогда ... но я удивлен, что это не работает ... Было бы интересно, если бы вы добавили в свой вопрос дополнительную информацию о том, как вы создали этот фрейм данных.
Я создал этот фрейм данных с помощью векторного ассемблера. Предложение, которое вы сделали, не удалось из-за странной ошибки - import org.apache.spark.mllib.linalg.Vector java.lang.ClassCastException: org.apache.spark.ml.linalg.DenseVector не может быть приведен в org.apache.spark.mllib.linalg.DenseVector
Это сработало Оли - getAs[org.apache.spark.ml.linalg.Vector] используйте полный путь
Хорошо, теперь я знаю, что не так. Вы используете SparkML, я погуглил документ и наткнулся на старую искровую мллиб. Я снова исправлю ответ :)
import org.apache.spark.ml.linalg.Vectors var x = df.head(1)(0).getAs[org.apache.spark.ml.linalg.Vector](0).toArray x.length - мурлыкать
Отлично :) Ответ исправлен!
Давайте продолжить обсуждение в чате.
Как преобразовать обернутый массив в обычный двойной массив?