如何简化基于两列条件的Pandas类别计数代码?
简化Pandas年龄组合统计代码的方法
先看原始数据和需求:
我们有如下Pandas DataFrame:
import pandas as pd data = pd.DataFrame({ 'Age1': [45, 48, 52, 51, 48, 45, 62, 47, 65, 50], 'Age2': [37, 68, 71, 54, 67, 59, 95, 56, 41, 42] })
需要按照<40、40-50、50-60、>60四个类别,统计Age1与Age2两两组合的数量。原代码通过重复编写布尔索引实现,非常冗余,我们可以用Pandas的内置函数大幅简化代码。
简化方案
核心思路是用pd.cut对年龄列进行分箱,再用pd.crosstab统计交叉频数:
# 定义区间边界和对应标签 bins = [-float('inf'), 40, 50, 60, float('inf')] labels = ['<40', '40-50', '50-60', '>60'] # 对两个年龄列分箱后生成交叉表,再转为目标列表格式 count = pd.crosstab( pd.cut(data['Age2'], bins=bins, labels=labels), pd.cut(data['Age1'], bins=bins, labels=labels) ).values.tolist() print(count)
运行结果和原代码完全一致:
[[0, 1, 0, 0], [0, 0, 1, 1], [0, 2, 1, 0], [0, 2, 1, 1]]
进一步精简(一行实现)
如果追求极致简洁,可以把分箱逻辑直接嵌入crosstab,无需额外变量:
count = pd.crosstab( pd.cut(data['Age2'], bins=[-float('inf'),40,50,60,float('inf')], labels=['<40','40-50','50-60','>60']), pd.cut(data['Age1'], bins=[-float('inf'),40,50,60,float('inf')], labels=['<40','40-50','50-60','>60']) ).values.tolist()
优势说明
- 避免了重复编写大量冗余的布尔判断逻辑,代码更简洁易读
- 利用Pandas内置的向量化操作,效率比循环/多次切片更高
- 后续如果需要调整区间或标签,只需修改
bins和labels即可,维护成本低
内容的提问来源于stack exchange,提问作者Aristocrat
相关产品推荐
相关产品推荐

