将结构数组分解为Spark

时间:2017-11-29 13:00:23

标签: scala apache-spark dataframe

我想将一组结构分解为列(由结构字段定义)。 E.g。

root
 |-- arr: array (nullable = true)
 |    |-- element: struct (containsNull = true)
 |    |    |-- id: long (nullable = false)
 |    |    |-- name: string (nullable = true)

应转换为

root
 |-- id: long (nullable = true)
 |-- name: string (nullable = true)

我可以用

实现这一目标
df
  .select(explode($"arr").as("tmp"))
  .select($"tmp.*")

如何在单个选择语句中执行此操作?

我认为这可行,不幸的是它没有:

df.select(explode($"arr")(".*"))
  

线程中的异常" main" org.apache.spark.sql.AnalysisException:没有   这样的struct field。* in col;

1 个答案:

答案 0 :(得分:0)

单步解决方案仅适用于MapType列:

val df = Seq(Tuple1(Map((1L, "bar"), (2L, "foo")))).toDF

df.select(explode($"_1") as Seq("foo", "bar")).show

+---+---+
|foo|bar|
+---+---+
|  1|bar|
|  2|foo|
+---+---+

使用数组,您可以使用flatMap

val df = Seq(Tuple1(Array((1L, "bar"), (2L, "foo")))).toDF
df.as[Seq[(Long, String)]].flatMap(identity)

单个SELECT语句可以用SQL编写:

 df.createOrReplaceTempView("df")

spark.sql("SELECT x._1, x._2 FROM df LATERAL VIEW explode(_1) t AS x")