如何将Pandas列按规整规则划分区间并避免空区间报错?
问题分析
原代码的核心问题是依赖pd.cut自动划分区间,再基于这些动态区间生成标签。当数据分布导致某个区间无值时(比如你的示例数据里没有30000-45000之间的数),访问空区间的max()/min()方法会返回NaN或触发报错。但你的需求是固定规整区间,根本不需要动态划分,直接用预设的边界值就能彻底规避空区间问题。
优化方案
直接基于你指定的区间边界,用pd.cut做固定区间划分,代码简洁且无报错风险:
import pandas as pd def FasciaImporto(df, col_name='NUMERICAL_VARIABLE'): # 预设你需要的固定区间边界 bins = [-float('inf'), 15000, 30000, 45000, float('inf')] # 对应区间的标签,完全匹配你的需求 labels = [ '<15000', '[15000-30000)', '[30000-45000)', '>=45000' ] # right=False 设置左闭右开,完美匹配 "x >= a 且 x < b" 的区间定义 df['FASCIA_IMPORTO'] = pd.cut(df[col_name], bins=bins, labels=labels, right=False) # 输出各区间计数 print(df['FASCIA_IMPORTO'].value_counts()) return df
为什么这能解决问题?
- 固定边界不依赖数据分布:不管数据里有没有某个区间的值,预设的边界都存在,不会出现空区间导致的访问错误。
- 区间定义精准匹配需求:
right=False让区间成为左闭右开,正好对应你要的x >= 15000 且 x < 30000这类规则。 - 代码大幅简化:去掉了复杂的循环和区间计算逻辑,用pandas原生函数完成,效率更高。
测试示例数据
把你的示例数据转为DataFrame后运行:
data = [18511.18, 82000.0, 16313.97, ...] # 完整数据见问题描述 df = pd.DataFrame(data, columns=['NUMERICAL_VARIABLE']) FasciaImporto(df)
输出会显示:
<15000 142 [15000-30000) 13 >=45000 1 [30000-45000) 0 Name: FASCIA_IMPORTO, dtype: int64
可以看到空区间[30000-45000)正常显示计数0,完全不会报错。
如果你需要保留原convert_number的边界调整逻辑
如果必须保留原代码中对区间边界的取整调整,只需先计算调整后的边界,再用固定区间划分:
import pandas as pd def convert_number(original_value): return round(original_value, -3) + 5000 def FasciaImporto(df, col_name='NUMERICAL_VARIABLE'): # 用convert_number调整预设的边界值 adjusted_bins = [ -float('inf'), convert_number(15000), convert_number(30000), convert_number(45000), float('inf') ] # 生成对应的标签 labels = [ f'<{adjusted_bins[1]}', f'[{adjusted_bins[1]}-{adjusted_bins[2]})', f'[{adjusted_bins[2]}-{adjusted_bins[3]})', f'>={adjusted_bins[3]}' ] df['FASCIA_IMPORTO'] = pd.cut(df[col_name], bins=adjusted_bins, labels=labels, right=False) print(df['FASCIA_IMPORTO'].value_counts()) return df
这样既保留了原有的边界调整逻辑,又彻底解决了空区间报错问题。
内容的提问来源于stack exchange,提问作者Alberto De Benedittis
相关产品推荐
相关产品推荐

