Как преобразовать плотный вектор Spark в отдельные столбцы с индексом в Scala? - PullRequest
0 голосов
/ 20 февраля 2020

Я хочу преобразовать векторы с плотной искрой в отдельные столбцы с индексом в Scala? Надеюсь на помощь, пожалуйста ~ ~ 1001 *

У меня есть датафрейм после minMaxScaler:

+---+--------+--------------------+---------------------+
| id|category|minMaxScalerFeatures|scaledFeatures_output|
+---+--------+--------------------+---------------------+
|  0|      66|          [0.0,66.0]|            [0.0,0.0]|
|  1|      98|          [1.0,98.0]|            [0.5,1.0]|
|  2|      90|          [2.0,90.0]|           [1.0,0.75]|
+---+--------+--------------------+---------------------+

Я хочу получить значение после скейлера с их индексом, например шаблон "index: value", который Тип строки:

+---+--------+--------------------+-----------------------+
| id|category|minMaxScalerFeatures|scaledFeatures_output  |
+---+--------+--------------------+-----------------------+
|  0|      66|          [0.0,66.0]|            0:0.0,1:0.0|
|  1|      98|          [1.0,98.0]|            0:0.5,1:1.0|
|  2|      90|          [2.0,90.0]|           0:1.0,1:0.75|
+---+--------+--------------------+-----------------------+

Код для генерации данных:

import org.apache.spark.ml.feature._
import org.apache.spark.sql.functions.udf
import org.apache.spark.sql.DataFrame
import org.apache.spark.sql.functions._

val df_1 = Seq((0, 66),(1, 98),(2, 90)).toDF("id", "category")

val minMax_columns = Array("id", "category")

val assembler = new VectorAssembler()
  .setInputCols(minMax_columns)
  .setOutputCol("minMaxScalerFeatures")

val scaler = new MinMaxScaler()
  .setInputCol("minMaxScalerFeatures")
  .setOutputCol("scaledFeatures_output")

val dataset = assembler.transform(df_1)

val scalerModel = scaler.fit(dataset)

val scaledData = scalerModel.transform(dataset)

Большое спасибо ~:)

1 Ответ

1 голос
/ 20 февраля 2020

Вопрос в том, как вы выполните эту задачу в массиве. Я бы лично сделал это (что может быть не оптимально, но это работает):

var s = ""
for(i <- 0 until array.length) s = s + s"$i:${a(i)}"
s = s.dropRight(1)

Теперь вы можете включить это в пользовательскую функцию, и это сделано:

import org.apache.spark.ml.linalg.DenseVector
import org.apache.spark.sql.functions.udf
val myudf = udf((arr: DenseVector) => {
    val a = arr.toArray
    var s = ""
    for(i <- 0 until a.length) s = s + s"$i:${a(i)},"
    s.dropRight(1)
})
...