【问题标题】:pivot one column into multiple columns in Pyspark/Python在 Pyspark/Python 中将一列转为多列
【发布时间】:2021-02-17 15:46:32
【问题描述】:

我在这一行发现了和我类似的情况,但是他使用的是 SQL server,而不是 pyspark/python:Pivoting Multiple Columns Based On a Single Column

我的日期集如下:

ID       Date             Class
1       2021/01/01        math, english
1       2021/01/02        math, english
1       2021/01/03        chinese
1       2021/01/04        math, chemistry
1       2021/01/05        math, english
1       2021/01/06        Chinese
2       2021/01/01        PE
2       2021/01/02        math, chinese
2       2021/01/03        math, english
2       2021/01/04        math, chinese
.......

期望的输出应该是:

ID       Date_1             schedule_1       Date_2       schedule_2     Date_3      schedule_3
1       2021/01/01        math, english      2021/01/03    chinese      2021/01/05   math, chemistry... 
1       2021/01/02        math, english      2021/01/06    chinese...
1       2021/01/05        math, english....
2       2021/01/01        PE                 2021/01/02    math, chinese     2021/01/03  math, english
2                                            2021/01/04    math, chinese

我正在计划使用 pivot 和 groupby,这是我当前的代码,它不起作用,我不知道如何解决它。

line2 = line\
.select("ID")\
.groupBy("ID","Class")\
    .pivot("Date","Class")\
    .agg(expr("coalesce(first(Class), \" \")"))

我们将不胜感激任何帮助、想法或建议。

【问题讨论】:

    标签: apache-spark pyspark group-by apache-spark-sql pivot


    【解决方案1】:

    有点棘手,需要更多的争论:

    import pyspark.sql.functions as F
    from pyspark.sql import Window
    
    df2 = df.withColumn(
        'rn',
        F.row_number().over(Window.partitionBy('ID', 'Class').orderBy('Date'))
    ).withColumn(
        'mindate',
        F.min('Date').over(Window.partitionBy('ID', 'Class'))
    ).withColumn(
        'rn2',
        F.dense_rank().over(Window.partitionBy('ID').orderBy('mindate'))
    ).groupBy('ID', 'rn').pivot('rn2').agg(
        F.first(F.struct('Date', 'Class'))
    ).orderBy('ID', 'rn')
    
    df3 = df2.select(
        'ID',
        *[f'{c}.*' for c in df2.columns[2:]]
    )
    
    df3.show(truncate=False)
    +---+----------+-------------+----------+-------------+----------+---------------+
    |ID |Date      |Class        |Date      |Class        |Date      |Class          |
    +---+----------+-------------+----------+-------------+----------+---------------+
    |1  |2021/01/01|math, english|2021/01/03|chinese      |2021/01/04|math, chemistry|
    |1  |2021/01/02|math, english|2021/01/06|chinese      |null      |null           |
    |1  |2021/01/05|math, english|null      |null         |null      |null           |
    |2  |2021/01/01|PE           |2021/01/02|math, chinese|2021/01/03|math, english  |
    |2  |null      |null         |2021/01/04|math, chinese|null      |null           |
    +---+----------+-------------+----------+-------------+----------+---------------+
    

    【讨论】:

    • 嗨 MCK,感谢您提供代码,我尝试了此代码,但看起来它只是将所有可能的类组合排列为列。我稍微编辑了我的问题,希望更清楚。谢谢
    • @yokielove 完全重写了我的答案。看看效果是否更好...?
    • 非常感谢!我了解大部分代码,只是一个小问题:[f'{c}.' for c in df2.columns[2:]] 这一行是什么意思或定义?
    • @yokielove 是一个格式字符串,它替换每列的名称并添加一个.* 以扩展结构
    猜你喜欢
    • 2022-06-11
    • 2020-02-10
    • 1970-01-01
    • 1970-01-01
    • 2018-03-09
    • 1970-01-01
    • 2017-11-21
    • 2021-12-30
    • 2020-12-07
    相关资源
    最近更新 更多