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

如何在PySpark中为列的数值计数分配区间并生成对应列

PySpark实现列计数区间分配

实现步骤

1. 计算目标列的数值总数(含重复值)

先统计列A、列B的非空值总数(含重复值,即该列所有值的数量):

from pyspark.sql import functions as F

# 假设已有目标DataFrame df
count_a = df.select(F.count(F.col("A"))).collect()[0][0]
count_b = df.select(F.count(F.col("B"))).collect()[0][0]

2. 定义区间映射逻辑

可以通过自定义函数匹配计数对应的区间,也可以直接用when表达式实现:

方法一:自定义函数映射区间

先定义区间规则,再编写匹配函数:

# 定义指定区间池
interval_rules = [
    (1000, 3000, "(1000-3000)"),
    (3001, 7000, "(3001-7000)"),
    (7001, 20000, "(7001-20000)"),
    (20001, 500000, "(20001-500000)")
]

def match_interval(count_val):
    for lower, upper, interval_str in interval_rules:
        if lower <= count_val <= upper:
            return interval_str
    return None  # 处理计数不在区间内的情况

# 获取列A、B对应的区间字符串
interval_c = match_interval(count_a)
interval_d = match_interval(count_b)
方法二:直接用when条件表达式

如果区间数量较少,也可以直接用Spark的条件判断语法:

# 为列A匹配区间并生成列C
df = df.withColumn("C", 
    F.when((count_a >= 1000) & (count_a <= 3000), "(1000-3000)")
     .when((count_a >= 3001) & (count_a <= 7000), "(3001-7000)")
     .when((count_a >= 7001) & (count_a <= 20000), "(7001-20000)")
     .when((count_a >= 20001) & (count_a <= 500000), "(20001-500000)")
     .otherwise(None)
)

# 同理生成列D
df = df.withColumn("D", 
    F.when((count_b >= 1000) & (count_b <= 3000), "(1000-3000)")
     .when((count_b >= 3001) & (count_b <= 7000), "(3001-7000)")
     .when((count_b >= 7001) & (count_b <= 20000), "(7001-20000)")
     .when((count_b >= 20001) & (count_b <= 500000), "(20001-500000)")
     .otherwise(None)
)

3. 添加区间结果列

将匹配到的区间作为常量列添加到原DataFrame中(方法一的后续操作):

df = df.withColumn("C", F.lit(interval_c))
df = df.withColumn("D", F.lit(interval_d))

补充说明

  • 如果需要统计列中去重后的数值数量,只需将F.count(F.col("A"))替换为F.countDistinct(F.col("A"))即可。
  • 若计数不在指定区间池内,代码默认返回None,可根据需求修改otherwise的返回值。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.17 08:10:37