在pyspark/python中使用不同的值组合多行

jum4pzuy  于 2021-07-13  发布在  Spark
关注(0)|答案(2)|浏览(402)

我有一张如下的table:

ID Date         Class     Level
1  2021/01/01    math      1
1  2021/01/01    english   1
1  2021/01/01    history   1

我现在的代码是

grouped_df = df\
    .groupby('ID','Date')\
    .agg(collect_list('class').alias("class"),collect_list('level').alias("level"))\
    .withColumn("class", concat_ws(", ", "class"))\
    .withColumn("level", concat_ws(", ", "level"))

代码给我的输出是这样的:

ID Date         Class                       Level
    1  2021/01/01    math, english,history      1, 1, 1

因为我想进行联合行排序,所以我使用 concat_ws ,但是阶级的顺序不是按欲望来排序的,在做这些事情的时候,有没有什么办法来排序呢 concat_ws() ? 我想合并 class 按字母顺序排序。就像 English, history, math . 但是当我做concat时,输出可以是 math_english,history, 或者 history, math, English .
有没有一种方法可以使输出如下所示:

ID Date        Class                       Level
  1  2021/01/01  english,history,math        1
mkshixfv

mkshixfv1#

你可以用 collect_set 要删除重复项:

grouped_df = df\
    .groupby('ID','Date')\
    .agg(collect_list('class').alias("class"),collect_set('level').alias("level"))\
    .withColumn("class", concat_ws(", ", "class"))\
    .withColumn("level", concat_ws(", ", "level"))

如果总是只有一个级别,也可以考虑按级别分组,例如。

grouped_df = df\
    .groupby('ID','Date', 'level')\
    .agg(collect_list('class').alias("class"))\
    .withColumn("class", concat_ws(", ", "class"))

编辑:如果要对数组排序,可以使用 sort_array :

grouped_df = df\
    .groupby('ID','Date')\
    .agg(sort_array(collect_list('class')).alias("class"),collect_set('level').alias("level"))\
    .withColumn("class", concat_ws(", ", "class"))\
    .withColumn("level", concat_ws(", ", "level"))
cdmah0mi

cdmah0mi2#

获取的唯一值 level 使用 collect_set 并下令 class 无法使用的值 array_sort 使用spark 2.3,但您可以使用 collect_list 通过有序窗口获取排序列表,而不是使用通常会导致性能不佳的自定义项:

from pyspark.sql import Window
from pyspark.sql import functions as F

w = Window.partitionBy("ID", "Date").orderBy("Class")

grouped_df = df.withColumn("Class", F.collect_list("Class").over(w)) \
    .withColumn("Level", F.collect_set("Level").over(w)) \
    .groupBy("ID", "Date") \
    .agg(
    F.concat_ws(",", F.max("Class")).alias("Class"),
    F.concat_ws(",", F.max("Level")).alias("Level")
)

grouped_df.show(truncate=False)

# +---+----------+--------------------+-----+

# |ID |Date      |Class               |Level|

# +---+----------+--------------------+-----+

# |1  |2021/01/01|english,history,math|1    |

# +---+----------+--------------------+-----+

相关问题