【发布时间】:2020-08-24 11:11:51
【问题描述】:
我有一个包含数组类型列的输入数据框。数组中的每个条目都是一个结构,由一个键(大约四个值之一)和一个值组成。我想把它变成一个数据框,每个可能的键有一列,并且该值不在该行的数组中的空值。任何数组中的键都不会重复,但它们可能会乱序或丢失。
到目前为止,我得到的最好的是
val wantedCols =df.columns
.filter(_ != arrayCol)
.filter(_ != "col")
val flattened = df
.select((wantedCols.map(col(_)) ++ Seq(explode(col(arrayCol)))):_*)
.groupBy(wantedCols.map(col(_)):_*)
.pivot("col.key")
.agg(first("col.value"))
这正是我想要的,但它很可怕,我不知道在每一列上分组的后果是什么。这样做的正确方法是什么?
编辑:示例输入/输出:
case class testStruct(name : String, number : String)
val dfExampleInput = Seq(
(0, "KY", Seq(testStruct("A", "45"))),
(1, "OR", Seq(testStruct("A", "30"), testStruct("B", "10"))))
.toDF("index", "state", "entries")
.show
+-----+-----+------------------+
|index|state| entries|
+-----+-----+------------------+
| 0| KY| [[A, 45]]|
| 1| OR|[[A, 30], [B, 10]]|
+-----+-----+------------------+
val dfExampleOutput = Seq(
(0, "KY", "45", null),
(1, "OR", "30", "10"))
.toDF("index", "state", "A", "B")
.show
+-----+-----+---+----+
|index|state| A| B|
+-----+-----+---+----+
| 0| KY| 45|null|
| 1| OR| 30| 10|
+-----+-----+---+----+
进一步编辑:
我自己提交了一个解决方案(见下文),只要您事先知道密钥(在我的情况下我知道),就可以很好地处理这个问题。如果找到密钥是一个问题,另一个答案包含处理该问题的代码。
【问题讨论】:
-
您可以添加预期的示例输入和输出吗?
-
将给定的输入和预期的输出添加到您的问题中会非常有帮助,请查看this 帖子了解更多详情
-
@Srinivas 编辑了它。担心它有点不清楚(没有显示我的预期) - “条目”列是一个结构数组。
-
@AlexandrosBiratsis 在中编辑了
-
@Edward 你知道条目数组的大小,它是固定的还是不固定的?此外,如果可能,pivot 是 Spark 中最繁重的操作之一,您应该避免它
标签: scala apache-spark