如何编写循环为DataFrame新增列,按COL2、COL3分组计算出现百分比
问题描述
现有如下DataFrame:
| COL1 | COL2 | COL3 | COL4 | COL5 | COL6 |
|---|---|---|---|---|---|
| S1 | A | Apples | Aisle 1 | N | Section 2 |
| S1 | A | Apples | Aisle 2 | Y | Section 2 |
| S1 | A | Apples | Aisle 1 | Y | Section 2 |
| S2 | A | Apples | Aisle 1 | N | Section 2 |
| S1 | B | Bananas | Aisle 2 | N | Section 2 |
| S1 | B | Bananas | Aisle 1 | N | Section 2 |
需要忽略COL1,以COL2和COL3为分组键,计算COL4至COL6每个值在对应分组内的出现百分比,最终得到如下结果:
| COL1 | COL2 | COL3 | COL4 | COL5 | COL6 | COL4_PCT | COL5_PCT | COL6_PCT |
|---|---|---|---|---|---|---|---|---|
| S1 | A | Apples | Aisle 1 | N | Section 2 | 0.75 | 0.50 | 1 |
| S1 | A | Apples | Aisle 2 | Y | Section 2 | 0.25 | 0.50 | 1 |
| S1 | A | Apples | Aisle 1 | Y | Section 2 | 0.75 | 0.50 | 1 |
| S2 | A | Apples | Aisle 1 | N | Section 2 | 0.75 | 0.50 | 1 |
| S1 | B | Bananas | Aisle 2 | N | Section 2 | 0.50 | 1 | 1 |
| S1 | B | Bananas | Aisle 1 | N | Section 2 | 0.50 | 1 | 1 |
解决方案
无需编写循环,用Pandas的groupby结合transform就能高效实现,代码如下:
import pandas as pd # 构造示例DataFrame data = { 'COL1': ['S1', 'S1', 'S1', 'S2', 'S1', 'S1'], 'COL2': ['A', 'A', 'A', 'A', 'B', 'B'], 'COL3': ['Apples', 'Apples', 'Apples', 'Apples', 'Bananas', 'Bananas'], 'COL4': ['Aisle 1', 'Aisle 2', 'Aisle 1', 'Aisle 1', 'Aisle 2', 'Aisle 1'], 'COL5': ['N', 'Y', 'Y', 'N', 'N', 'N'], 'COL6': ['Section 2']*6 } df = pd.DataFrame(data) # 批量计算COL4-COL6的分组占比 for col in ['COL4', 'COL5', 'COL6']: # 用transform将分组计算的占比映射回原数据的每一行 df[f'{col}_PCT'] = df.groupby(['COL2', 'COL3'])[col].transform( lambda x: x.map(x.value_counts(normalize=True)) ) # 输出结果 print(df)
代码逻辑说明
- 分组:通过
groupby(['COL2', 'COL3'])将数据按指定的标识键分组 - 计算占比:
x.value_counts(normalize=True)会统计分组内每个值的出现占比(返回0-1之间的小数) - 映射回原数据:
transform方法会将分组计算的结果广播回原DataFrame的对应行,确保每条记录都能匹配到所属分组的百分比
运行后即可得到目标结果,比如COL2=A、COL3=Apples的分组共4条记录,COL4中"Aisle 1"出现3次,占比0.75;COL5中"N"和"Y"各出现2次,占比0.5,与预期完全一致。
内容的提问来源于stack exchange,提问作者NEWBIE
相关产品推荐
相关产品推荐

