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

PySpark中按Language分组计算Male与Female数量比例的优雅实现

问题描述

我有一个如下所示的PySpark DataFrame:

+------------+-------------+
|Gender      |     Language|
+------------+-------------+
|        Male|      Spanish|
|      Female|      English|
|      Female|       Indian|
|      Female|      Spanish|
|      Female|       Indian|
|        Male|      English|
|        Male|      English|
|      Female|Latin Spanish|
|        Male|      Spanish|
|      Female|      English|
|        Male|       Indian|
|        Male|      Catalan|
|        Male|      Spanish|
|        Male|      Russian|
|        Male|      Spanish|
|        Male|      Spanish|
|      Female|      Russian|
|      Female|      Spanish|
|        Male|      English|
|        Male|      Spanish|
+------------+-------------+

我希望获取每种Language对应的Male与Female的数量比例,该如何在PySpark中实现?

我原本的思路是先统计分组数量,再遍历每种语言:

counts = df.groupby('Language', 'Gender').count()
# loop across all languages and both genders
counts.filter((counts.Language == 'Italian') & (counts.Gender == 'Male')).show()

但有没有更优雅的实现方式?

优雅实现方案

方法1:使用pivot透视表

先按Language分组,对Gender进行透视得到各性别的数量,再直接计算比例:

from pyspark.sql.functions import col

# 分组透视并填充空值(处理某语言只有单一性别的情况)
gender_counts = df.groupBy("Language")\
    .pivot("Gender")\
    .count()\
    .na.fill(0)

# 计算男女数量比例,可根据需求调整分子分母
result = gender_counts.withColumn(
    "Male_Female_Ratio",
    col("Male") / col("Female")
).withColumn(
    "Female_Male_Ratio",
    col("Female") / col("Male")
)

result.show()

该方法直接生成包含各语言男女数量及对应比例的DataFrame,无需手动遍历。

方法2:使用条件聚合

通过when函数在分组阶段直接统计男女数量,再推导比例:

from pyspark.sql.functions import count, when

# 聚合阶段统计各语言下男女数量
gender_agg = df.groupBy("Language")\
    .agg(
        count(when(col("Gender") == "Male", 1)).alias("Male_Count"),
        count(when(col("Gender") == "Female", 1)).alias("Female_Count")
    )\
    .na.fill(0)

# 计算比例
result = gender_agg.withColumn(
    "Male_Female_Ratio",
    col("Male_Count") / col("Female_Count")
)

result.show()

这种方式更灵活,避免了透视表在性别类别较多时可能产生的性能开销。

方法3:使用窗口函数计算占比

如果需要的是各性别在对应语言总人数中的占比(比如Male占该语言总人数的比例),可以用窗口函数:

from pyspark.sql.functions import count, col
from pyspark.sql.window import Window

window_spec = Window.partitionBy("Language")

# 计算各语言总人数,再推导性别占比
result = df.groupBy("Language", "Gender")\
    .count()\
    .withColumn("Total_Per_Language", count("*").over(window_spec))\
    .withColumn("Gender_Ratio", col("count") / col("Total_Per_Language"))\
    .orderBy("Language", "Gender")

result.show()

该方案适合需要展示各性别在对应语言中占比的场景。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.30 00:23:36