【发布时间】:2019-07-08 08:44:53
【问题描述】:
我有一个包含不同时间周期(1/6、3/6、6/6 等)列的 DF,并希望“分解”所有列以创建一个新的 DF,其中每一行都是一个 1/6 周期。
from pyspark import Row
from pyspark.sql import SparkSession
from pyspark.sql.functions import explode, arrays_zip, col
spark = SparkSession.builder \
.appName('DataFrame') \
.master('local[*]') \
.getOrCreate()
df = spark.createDataFrame([Row(a=1, b=[1, 2, 3, 4, 5, 6], c=[11, 22, 33], d=['foo'])])
| a| b| c| d|
+---+------------------+------------+-----+
| 1|[1, 2, 3, 4, 5, 6]|[11, 22, 33]|[foo]|
+---+------------------+------------+-----+
我正在做爆炸:
df2 = (df.withColumn("tmp", arrays_zip("b", "c", "d"))
.withColumn("tmp", explode("tmp"))
.select("a", col("tmp.b"), col("tmp.c"), "d"))
但输出不是我想要的:
| a| b| c| d|
+---+---+----+-----+
| 1| 1| 11|[foo]|
| 1| 2| 22|[foo]|
| 1| 3| 33|[foo]|
| 1| 4|null|[foo]|
| 1| 5|null|[foo]|
| 1| 6|null|[foo]|
+---+---+----+-----+
我希望它看起来像这样:
| a| b| c| d|
+---+---+---+---+
| 1| 1| 11|foo|
| | 2| | |
| | 3| 22| |
| | 4| | |
| | 5| 33| |
| | 6| | |
+---+---+---+---+
我是 Spark 的新手,从一开始我就有很复杂的话题! :)
2019-07-15 更新:也许有人有不使用 UDF 的解决方案? -> 由@jxc 回答
2019-07-17 更新:也许有人有一个解决方案,如何以更复杂的顺序更改空 值序列?就像在c - Null, 11, Null, 22, Null, 33 或更复杂的情况下,我们希望在列d 第一个值是Null,下一个是foo,然后是Null, Null, Null:
| a| b| c| d|
+---+---+---+---+
| 1| 1| | |
| | 2| 11|foo|
| | 3| | |
| | 4| 22| |
| | 5| | |
| | 6| 33| |
+---+---+---+---+
【问题讨论】: