如何在Pandas中实现一个activityCode映射多个activityName并拆分生成多行数据
Pandas: 映射并拆分含多值的activityCode行
这个问题很典型——当映射值是多值列表时,map方法只会把整个列表当成单个单元格内容,不会自动拆分出多行。这里给你两种实用的解决方案,轻松实现你想要的效果:
方法一:用explode快速拆分(推荐,Pandas 0.25+可用)
这是最简洁高效的方式,先完成映射,再用explode把含列表的单元格炸开成多行:
import pandas as pd # 原始数据 df = pd.DataFrame( [[1, '02', 3], [2, '01', 5], [3, '03', 8], [4, '04', 1]], columns=['Student', 'activityCode', 'pts'] ) # 定义映射字典,注意'02'对应列表 activity_map = { '01': 'Swimming', '02': ['Swimming', 'Football'], '03': 'Running', '04': 'Football' } # 先完成映射,得到包含列表的activityName列 df['activityName'] = df['activityCode'].map(activity_map) # 炸开列表单元格,自动拆分多行,最后重置索引 result_df = df.explode('activityName').reset_index(drop=True) # 查看结果 print(result_df)
运行后输出的结果完全符合你的预期:
| Student | activityCode | pts | activityName |
|---|---|---|---|
| 1 | 02 | 3 | Swimming |
| 1 | 02 | 3 | Football |
| 2 | 01 | 5 | Swimming |
| 3 | 03 | 8 | Running |
| 4 | 04 | 1 | Football |
方法二:自定义函数+apply(兼容旧版Pandas)
如果你的Pandas版本低于0.25(explode是0.25版本新增的),可以用这种方式处理:
import pandas as pd df = pd.DataFrame( [[1, '02', 3], [2, '01', 5], [3, '03', 8], [4, '04', 1]], columns=['Student', 'activityCode', 'pts'] ) # 把所有映射值统一改成列表,方便函数统一处理 activity_map = { '01': ['Swimming'], '02': ['Swimming', 'Football'], '03': ['Running'], '04': ['Football'] } def expand_activity(row): # 获取当前行对应的活动名称列表 name_list = activity_map[row['activityCode']] # 生成对应数量的行数据,其他列保持重复 return pd.Series({ 'Student': [row['Student']] * len(name_list), 'activityCode': [row['activityCode']] * len(name_list), 'pts': [row['pts']] * len(name_list), 'activityName': name_list }) # 应用函数后炸开所有列,再重置索引 result_df = df.apply(expand_activity, axis=1).explode().reset_index(drop=True)
这个方法通过自定义函数,把每一行转换成包含列表的Series,再统一炸开拼接,同样能得到目标结果。
小提示
- 方法一中的
explode是专门为这种“单元格含列表需要拆分”的场景设计的,代码简洁且性能更好,优先推荐。 - 方法二中统一把映射值改成列表,避免了额外的类型判断逻辑,代码更健壮。
内容的提问来源于stack exchange,提问作者Wingyan Yip
相关产品推荐
相关产品推荐

