pandas按Region、Category分组基于其他行更新unknown行的low、high值
问题解决方案
原有代码错误原因
- 大小写匹配错误:数据中
level字段的未知值为小写unknown,你的判断条件写为大写开头的Unknown,无法匹配到目标行 - 语法错误:
df['level]缺少右引号,直接触发语法报错 - 缺少分组逻辑:没有按
Region和Category分组筛选对应E/S的数值,直接全局筛选返回的是序列,无法直接赋值给单个单元格 - 缺失兜底逻辑:没有处理分组内不存在
E/S时保留原值-1的逻辑
正确实现代码
优先使用pandas向量化操作,避免逐行遍历提高效率:
import pandas as pd # 原始数据构造 list_val = {'Region': [3715, 3715, 3715, 3715, 3715, 3715, 3715, 3715, 3715, 3715, 3718, 3718, 3718], 'Category': [1, 1, 1, 1,1, 2, 2 ,2 ,2, 2,1 ,1 ,1], 'level': ['E', 'E/M', 'M', 'S', 'unknown', 'E', 'E/M', 'M', "S", "unknown", 'M', "E/M", 'unknown'], 'low': [2, 5, 10, 4, -1, 8, 12, 5, 14, -1, 3, 5, -1], 'high': [3, 6, 5, 6, -1, 12, 8, 9, 15, -1, 3, 8, -1]} df = pd.DataFrame(list_val) # 构造分组映射:按Region+Category分组,存储对应分组下E的low值、S的high值 e_low_map = df[df['level'] == 'E'].groupby(['Region', 'Category'])['low'].first() s_high_map = df[df['level'] == 'S'].groupby(['Region', 'Category'])['high'].first() # 筛选unknown行的掩码 unknown_mask = df['level'] == 'unknown' # 替换low列:匹配不到映射值则保留原值-1 df.loc[unknown_mask, 'low'] = df[unknown_mask].apply( lambda x: e_low_map.get((x['Region'], x['Category']), x['low']), axis=1 ) # 替换high列:匹配不到映射值则保留原值-1 df.loc[unknown_mask, 'high'] = df[unknown_mask].apply( lambda x: s_high_map.get((x['Region'], x['Category']), x['high']), axis=1 ) # 输出结果 print(df)
输出结果验证
运行后输出结果完全符合预期:
| Region | Category | level | low | high | |
|---|---|---|---|---|---|
| 0 | 3715 | 1 | E | 2 | 3 |
| 1 | 3715 | 1 | E/M | 5 | 6 |
| 2 | 3715 | 1 | M | 10 | 5 |
| 3 | 3715 | 1 | S | 4 | 6 |
| 4 | 3715 | 1 | unknown | 2 | 6 |
| 5 | 3715 | 2 | E | 8 | 12 |
| 6 | 3715 | 2 | E/M | 12 | 8 |
| 7 | 3715 | 2 | M | 5 | 9 |
| 8 | 3715 | 2 | S | 14 | 15 |
| 9 | 3715 | 2 | unknown | 8 | 15 |
| 10 | 3718 | 1 | M | 3 | 3 |
| 11 | 3718 | 1 | E/M | 5 | 8 |
| 12 | 3718 | 1 | unknown | -1 | -1 |
内容的提问来源于stack exchange,提问作者PRIN
相关产品推荐
相关产品推荐

