如何将DataFrame中同一id的多行合并为一行并展开code列?
解决同一ID多行合并,Code列转独立列的问题
核心思路
先给每个ID的行添加组内序号,把Code列按序号拆分成新列,再和非Code列合并(默认假设同一ID下非Code列值一致,若不一致可调整聚合规则)。
具体实现步骤
以下是基于Pandas的完整代码示例:
1. 导入库并创建示例数据
import pandas as pd # 模拟你的数据结构 data = { 'id': [1,1,2], 'hours1': [8,8,7], 'hours2': [6,6,5], 'id_2': [101,101,102], 'status': ['active','active','inactive'], 'timeweeks': [202401,202401,202402], 'code1': ['A', None, 'B'], 'code2': [None, 'C', 'D'], 'code3': ['E', 'F', None] } df = pd.DataFrame(data)
2. 给每个ID的行添加组内序号
这个序号用来给后续的Code列命名(比如code1_1对应同一ID下第1行的code1值):
df['row_num'] = df.groupby('id').cumcount() + 1 # 从1开始编号,匹配你要的_1、_2后缀
3. 分离并处理非Code列
如果同一ID下非Code列值完全一致,直接去重保留唯一值:
non_code_cols = ['id', 'hours1', 'hours2', 'id_2', 'status', 'timeweeks'] non_code_df = df[non_code_cols].drop_duplicates(subset='id').set_index('id')
如果同一ID下非Code列存在不同值,替换成聚合逻辑即可,比如取第一个值:df.groupby('id')[non_code_cols].first(),或取均值、最大值等。
4. 处理Code列,转成带序号的独立列
用unstack把同一ID的多行Code值展开成宽表,并重命名列:
code_cols = ['code1', 'code2', 'code3'] code_df = df.set_index(['id', 'row_num'])[code_cols].unstack() # 重命名列,格式为「原列名_序号」 code_df.columns = [f'{col}_{num}' for col, num in code_df.columns]
5. 合并结果
把非Code列和处理后的Code列合并,得到最终格式的DataFrame:
result = non_code_df.join(code_df).reset_index() print(result)
结果示例
运行后会得到如下结构的结果:
| id | hours1 | hours2 | id_2 | status | timeweeks | code1_1 | code1_2 | code2_1 | code2_2 | code3_1 | code3_2 |
|---|---|---|---|---|---|---|---|---|---|---|---|
| 1 | 8 | 6 | 101 | active | 202401 | A | NaN | NaN | C | E | F |
| 2 | 7 | 5 | 102 | inactive | 202402 | B | NaN | D | NaN | NaN | NaN |
为什么groupby转字典不行?
直接用groupby转字典的方式,没法精准控制Code列的展开逻辑,容易把多行Code值打包成列表,而不是拆分成独立列。上面的方法通过序号标记+宽表转换,能精准实现你要的列名格式和结构。
内容的提问来源于stack exchange,提问作者Lurri
相关产品推荐
相关产品推荐

