Как сделать расширение списка в sql .functions.struct? - PullRequest
1 голос
/ 09 апреля 2020

Я хочу иметь возможность передавать список имен столбцов длиной n в struct, но мне не нужно жестко кодировать каждый столбец в struct. Расширение списка не похоже на struct. Есть ли способ сделать это?

Я на Spark 2.3.x, и я не могу обновить (если это проблема версии), так как это рабочий кластер.

import org.apache.spark.sql.functions._
import org.apache.spark.sql.Column

def randomInt = scala.util.Random.nextInt(100)

val zipData = sc.parallelize(
  Seq.fill(10){(randomInt, randomInt, randomInt)}
).toDF("x", "y", "z")

val cols = Seq("x", "y", "z")
val mappedCols = cols.foldLeft(Seq[Column]())((x, c) => x :+ col(c).alias(c))

// this doesn't work
zipData.withColumn("zipped", struct(mappedCols.head, mappedCols.tail: _*)).show

// it seems only hard coding work
zipData.withColumn("zipped", struct(mappedCols(0), mappedCols(1)).show
zipData.withColumn("zipped", struct(col("x"), col("y")).show

Ответы [ 2 ]

2 голосов
/ 09 апреля 2020

Использование .withColumn

zipData.withColumn("zipped",struct(mappedCols: _*)).show()
+---+---+---+------------+
|  x|  y|  z|      zipped|
+---+---+---+------------+
| 56| 46| 12|[56, 46, 12]|
| 80| 20| 20|[80, 20, 20]|
| 27| 82| 85|[27, 82, 85]|
| 89| 42| 45|[89, 42, 45]|
|  0| 75| 58| [0, 75, 58]|
| 97| 77| 54|[97, 77, 54]|
| 55| 32|  0| [55, 32, 0]|
| 82| 12| 97|[82, 12, 97]|
| 66| 82| 42|[66, 82, 42]|
| 61| 70| 95|[61, 70, 95]|
+---+---+---+------------+

Использование .selectExpr

val mappedCols=zipData.columns.mkString("struct(",",",") as zipped")
zipData.selectExpr("*",mappedCols).show()
+---+---+---+------------+
|  x|  y|  z|      zipped|
+---+---+---+------------+
| 41| 41| 51|[41, 41, 51]|
| 41| 54| 19|[41, 54, 19]|
| 54| 48| 13|[54, 48, 13]|
| 12| 90| 95|[12, 90, 95]|
| 76| 21| 44|[76, 21, 44]|
|  7| 29| 33| [7, 29, 33]|
| 66| 10| 92|[66, 10, 92]|
| 82|  4| 19| [82, 4, 19]|
|  8| 38| 97| [8, 38, 97]|
| 71| 51| 18|[71, 51, 18]|
+---+---+---+------------+

Использование .select

zipData.select(zipData.col("*"),struct(mappedCols: _*).alias("zipped")).show()
+---+---+---+------------+
|  x|  y|  z|      zipped|
+---+---+---+------------+
| 41| 41| 51|[41, 41, 51]|
| 41| 54| 19|[41, 54, 19]|
| 54| 48| 13|[54, 48, 13]|
| 12| 90| 95|[12, 90, 95]|
| 76| 21| 44|[76, 21, 44]|
|  7| 29| 33| [7, 29, 33]|
| 66| 10| 92|[66, 10, 92]|
| 82|  4| 19| [82, 4, 19]|
|  8| 38| 97| [8, 38, 97]|
| 71| 51| 18|[71, 51, 18]|
+---+---+---+------------+
1 голос
/ 09 апреля 2020

Рассматривая реализацию на github, мы можем только расширить имена строк; то есть следующие работы

sql .функции

zipData.withColumn("zipped", struct(cols.head, cols.tail: _*)).show
...