You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在PySpark中实现GroupBy Count的逆操作?

PySpark实现计数逆展开(GroupBy Count逆操作)的方法

需求说明

输入DataFrame包含班级、男性计数、女性计数三列,需要将计数展开为对应行数的记录:男性计数对应性别'm',女性计数对应性别'f',最终得到每个班级下每条记录对应单个性别的结果。

输入DataFrame构造

先模拟创建输入数据:

from pyspark.sql import SparkSession
from pyspark.sql.functions import array_repeat, explode, col

spark = SparkSession.builder.appName("count_unfold").getOrCreate()

data = [
    ("A", 2, 1),
    ("B", 3, 1),
    ("C", 0, 3),
    ("D", 2, 4)
]
input_df = spark.createDataFrame(data, ["班级(class)", "男性计数(malecount)", "女性计数(femalecount)"])

方法一:拆分男女数据分别展开后合并

这种方法逻辑直观,分别处理男性和女性的计数展开,再合并结果:

# 处理男性记录:过滤计数>0的行,生成对应数量的'm'数组并展开
male_df = input_df.filter(col("男性计数(malecount)") > 0) \
                  .select(
                      col("班级(class)").alias("班级(Class)"),
                      explode(array_repeat("m", col("男性计数(malecount)"))).alias("性别(Gender)")
                  )

# 处理女性记录:同理处理女性计数
female_df = input_df.filter(col("女性计数(femalecount)") > 0) \
                    .select(
                        col("班级(class)").alias("班级(Class)"),
                        explode(array_repeat("f", col("女性计数(femalecount)"))).alias("性别(Gender)")
                    )

# 合并两个结果DF
output_df = male_df.union(female_df)

# 查看结果(可选)
output_df.show()

方法二:先宽表转长表再统一展开

如果后续有更多性别列需要处理,这种方法扩展性更好,先把宽表转为长表(性别-计数的键值对),再统一展开:

from pyspark.sql.functions import expr

# 宽表转长表:将男女计数列转为性别和计数列
melted_df = input_df.select(
    col("班级(class)"),
    expr("stack(2, 'm', 男性计数(malecount), 'f', 女性计数(femalecount)) as (性别(Gender), 计数)")
).filter(col("计数") > 0)

# 展开计数为对应行数
output_df = melted_df.select(
    col("班级(class)").alias("班级(Class)"),
    explode(array_repeat(col("性别(Gender)"), col("计数"))).alias("性别(Gender)")
)

# 查看结果(可选)
output_df.show()

两种方法都能得到预期的输出结果,方法二更适合多性别列的场景,方法一逻辑更直白易理解。

内容的提问来源于stack exchange,提问作者pradeep nadarajan

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.10 15:15:42