Spark Scala создать несколько столбцов из массива столбца - PullRequest
0 голосов
/ 29 сентября 2019

Создание нескольких столбцов из столбца массива

Фрейм данных

Car name |  details
Toyota   | [[year,2000],[price,20000]]
Audi     | [[mpg,22]]

Ожидаемый фрейм данных

Car name | year | price | mpg
Toyota   | 2000 | 20000 | null
Audi     | null | null | 22

Ответы [ 2 ]

0 голосов
/ 30 сентября 2019

Вы можете попробовать это

Давайте определим данные

scala> val carsDF = Seq(("toyota",Array(("year", 2000), ("price", 100000))), ("Audi", Array(("mpg", 22)))).toDF("car", "details")
carsDF: org.apache.spark.sql.DataFrame = [car: string, details: array<struct<_1:string,_2:int>>]

scala> carsDF.show(false)
+------+-----------------------------+
|car   |details                      |
+------+-----------------------------+
|toyota|[[year,2000], [price,100000]]|
|Audi  |[[mpg,22]]                   |
+------+-----------------------------+

Разделение данных и доступ к значениям в данных

scala> carsDF.withColumn("split", explode($"details")).withColumn("col", $"split"("_1")).withColumn("val", $"split"("_2")).select("car", "col", "val").show
+------+-----+------+
|   car|  col|   val|
+------+-----+------+
|toyota| year|  2000|
|toyota|price|100000|
|  Audi|  mpg|    22|
+------+-----+------+

Определение списка столбцовобязательные

scala> val colNames = Seq("mpg", "price", "year", "dummy")
colNames: Seq[String] = List(mpg, price, year, dummy)

Использование поворота для указанных выше имен столбцов дает требуемый вывод.Задавая новые имена столбцов в последовательности, вы получаете ввод из одной точки

scala> weDF.groupBy("car").pivot("col", colNames).agg(avg($"val")).show
+------+----+--------+------+-----+
|   car| mpg|   price|  year|dummy|
+------+----+--------+------+-----+
|toyota|null|100000.0|2000.0| null|
|  Audi|22.0|    null|  null| null|
+------+----+--------+------+-----+

Это кажется более элегантным и простым способом достижения результата

0 голосов
/ 29 сентября 2019

Вы можете сделать это так

import org.apache.spark.functions.col
val df: DataFrame = Seq(
  ("toyota",Array(("year", 2000), ("price", 100000))),
  ("toyota",Array(("year", 2001)))
).toDF("car", "details")

 +------+-------------------------------+
 |car   |details                        |
 +------+-------------------------------+
 |toyota|[[year, 2000], [price, 100000]]|
 |toyota|[[year, 2001]]                 |
 +------+-------------------------------+

val newdf = df
  .withColumn("year", when(col("details")(0)("_1") === lit("year"), col("details")(0)("_2")).otherwise(col("details")(1)("_2")))
  .withColumn("price", when(col("details")(0)("_1") === lit("price"), col("details")(0)("_2")).otherwise(col("details")(1)("_2")))
  .drop("details")

newdf.show()
  +------+----+------+
  |   car|year| price|
  +------+----+------+
  |toyota|2000|100000|     
  |toyota|2001|  null|
  +------+----+------+
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...