【问题标题】:Explode multiple columns to rows in pyspark在pyspark中将多列分解为行
【发布时间】:2021-10-29 14:57:53
【问题描述】:

我有以下 spark 数据框。

Name     age     subject        parts
xxxx     21      Maths,Physics  I
yyyy     22      English,French I,II

我正在尝试在主题和以下部分中分解上述数据框。

预期输出:

Name     age     subject        parts
xxxx     21      Maths          I
xxxx     21      Physics        I
yyyy     22      English        I
yyyy     22      English        II
yyyy     22      French         I
yyyy     22      French         II

我尝试对主题和部分使用 array.zip,然后尝试使用 temp 列进行分解,但我在只有一个部分的地方得到了空值。

有没有办法在 Pyspark 中实现这一点。

【问题讨论】:

  • 你的架构是什么?
  • 姓名、年龄、主题和部分。都是字符串

标签: pyspark explode


【解决方案1】:

您只需要同时使用splitexplode

数据样本

df.show()
+----+---+--------------+-----+                                                 
|Name|age|       subject|parts|
+----+---+--------------+-----+
|xxxx| 21| Maths,Physics|    I|
|yyyy| 22|English,French| I,II|
+----+---+--------------+-----+

df.printSchema()
root
 |-- Name: string (nullable = true)
 |-- age: long (nullable = true)
 |-- subject: string (nullable = true)
 |-- parts: string (nullable = true)

数据转换

from pyspark.sql import functions as F

df.withColumn(
    "subject", F.explode(F.split("subject", ","))
).withColumn(
    "parts", F.explode(F.split("parts", ","))
).show()

+----+---+-------+-----+
|Name|age|subject|parts|
+----+---+-------+-----+
|xxxx| 21|  Maths|    I|
|xxxx| 21|Physics|    I|
|yyyy| 22|English|    I|
|yyyy| 22|English|   II|
|yyyy| 22| French|    I|
|yyyy| 22| French|   II|
+----+---+-------+-----+

【讨论】:

    【解决方案2】:

    您可以将它们分开,然后将它们重新组合在一起

    拆分主题

    df1 = (df
        .select('name', 'age', 'subject')
        .withColumn('subject', F.explode(F.split('subject', ',')))
    )
    
    # +----+---+-------+
    # |name|age|subject|
    # +----+---+-------+
    # |xxxx| 21|  Maths|
    # |xxxx| 21|Physics|
    # |yyyy| 22|English|
    # |yyyy| 22| French|
    # +----+---+-------+
    

    拆分部分

    df2 = (df
        .select('name', 'age', 'parts')
        .withColumn('parts', F.explode(F.split('parts', ',')))
    )
    
    # +----+---+-----+
    # |name|age|parts|
    # +----+---+-----+
    # |xxxx| 21|    I|
    # |yyyy| 22|    I|
    # |yyyy| 22|   II|
    # +----+---+-----+
    

    加入

    df1.join(df2, on=['name', 'age'])
    
    # +----+---+-------+-----+
    # |name|age|subject|parts|
    # +----+---+-------+-----+
    # |xxxx| 21|  Maths|    I|
    # |xxxx| 21|Physics|    I|
    # |yyyy| 22|English|    I|
    # |yyyy| 22|English|   II|
    # |yyyy| 22| French|    I|
    # |yyyy| 22| French|   II|
    # +----+---+-------+-----+
    

    【讨论】:

    • join 将添加一个无用的随机播放步骤,您可以通过直接在同一数据帧内爆炸来避免该步骤
    【解决方案3】:

    我通过将列作为列表传递给 for 循环并分解列表中每个元素的数据框来做到这一点

    【讨论】:

    • 这不是一个真正的答案......其他会发现你的问题的人无法释放这个简单的短语来理解他们在相同情况下应该做什么
    猜你喜欢
    • 2018-12-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-01-12
    • 1970-01-01
    • 2017-04-22
    • 1970-01-01
    相关资源
    最近更新 更多