如何用Python Pandas计算DataFrame中二元列与标称列的CH占比
问题描述
给定如下Pandas DataFrame:
数据类型
- ID - int64
- X1 - int64
- X2 - int64
- CH - int64
原始数据
| ID | X1 | X2 | CP | CH |
|---|---|---|---|---|
| 111 | 1 | 0 | 10-20 | 1 |
| 222 | 1 | 0 | 10-20 | 1 |
| 333 | 0 | 1 | 30-40 | 0 |
| 444 | 1 | 1 | 30-40 | 1 |
| 555 | 0 | 1 | 30-40 | 1 |
需要生成统计结果表,计算CP与X1=1的组合、CP与X2=1的组合下,CH=1的客户占比,且要包含所有指定的CP区间(10-20、20-30、30-40、40-50),最终期望结果如下:
| col_X | col_CP | CH_perc |
|---|---|---|
| X1 | 10-20 | 1.00 |
| X1 | 20-30 | 0 |
| X1 | 30-40 | 1.00 |
| X1 | 40-50 | 0 |
| X2 | 10-20 | 0 |
| X2 | 20-30 | 0 |
| X2 | 30-40 | 0.66 |
| X2 | 40-50 | 0 |
解决方案
可以通过以下步骤实现:
1. 准备完整的CP区间列表
首先定义所有需要统计的CP区间,确保结果中不会缺失:
cp_intervals = ['10-20', '20-30', '30-40', '40-50']
2. 构造交叉统计的基础数据
分别处理X1和X2的统计逻辑,再合并结果:
import pandas as pd # 加载原始数据(若已有DataFrame可跳过此步) df = pd.DataFrame({ 'ID': [111, 222, 333, 444, 555], 'X1': [1, 1, 0, 1, 0], 'X2': [0, 0, 1, 1, 1], 'CP': ['10-20', '10-20', '30-40', '30-40', '30-40'], 'CH': [1, 1, 0, 1, 1] }) # 统计X1=1时各CP区间的CH占比 x1_stats = df[df['X1'] == 1].groupby('CP')['CH'].agg( total='count', ch1='sum' ).reset_index() x1_stats['col_X'] = 'X1' x1_stats['CH_perc'] = x1_stats['ch1'] / x1_stats['total'] # 统计X2=1时各CP区间的CH占比 x2_stats = df[df['X2'] == 1].groupby('CP')['CH'].agg( total='count', ch1='sum' ).reset_index() x2_stats['col_X'] = 'X2' x2_stats['CH_perc'] = x2_stats['ch1'] / x2_stats['total']
3. 补全缺失的CP区间
构造包含所有col_X和col_CP组合的空表,再合并统计结果,确保无遗漏:
# 生成所有需要的组合 all_combinations = pd.MultiIndex.from_product( [['X1', 'X2'], cp_intervals], names=['col_X', 'col_CP'] ).to_frame(index=False) # 合并统计数据与全组合表 combined = pd.concat([x1_stats, x2_stats]) result = all_combinations.merge( combined[['col_X', 'CP', 'CH_perc']], left_on=['col_X', 'col_CP'], right_on=['col_X', 'CP'], how='left' ).drop('CP', axis=1) # 填充缺失值为0,保留两位小数 result['CH_perc'] = result['CH_perc'].fillna(0).round(2)
4. 查看最终结果
执行代码后,打印result即可得到目标表格:
print(result)
输出结果:
col_X col_CP CH_perc 0 X1 10-20 1.00 1 X1 20-30 0.00 2 X1 30-40 1.00 3 X1 40-50 0.00 4 X2 10-20 0.00 5 X2 20-30 0.00 6 X2 30-40 0.67 7 X2 40-50 0.00
关键说明
- 用
groupby分组统计每个CP区间的总客户数和CH=1的客户数,直接计算占比 - 通过
MultiIndex.from_product生成全量组合,避免遗漏指定的CP区间 - 左连接合并后用
fillna(0)填充无数据的占比,保证结果完整性
内容的提问来源于stack exchange,提问作者unbik
相关产品推荐
相关产品推荐

