Pandas中按ID分组并将重复行转为多列的实现问题
Pandas按ID分组多行转多列(兼容缺失值场景)
原代码失效的核心问题是用stack()会自动剔除缺失值,导致同一ID下的行计数错位,没法对应到后续的列扩展逻辑。下面是能正确处理含缺失值场景的实现方案:
实现步骤
- 给每个ID内的行分配连续序号(从1开始,确保缺失值不影响行计数)
- 通过透视(pivot)将行转成列,完整保留所有缺失值
- 重命名列名,贴合需求的
name/name2格式 - 调整列顺序,让输出结构更符合期望
完整代码
import pandas as pd import numpy as np # 带缺失值的示例数据 df = pd.DataFrame({'ID': [1, 2, 1, 4, 2, 6, 1], 'Name': ['led', 'peter', np.nan, np.nan, 'make', 'levi', 'kent'], 'food': [np.nan, 'oranges', 'banana', 'carrots', 'carrots', 'mango', 'banana'], 'color': ['red', 'blue', 'pink', 'red', np.nan, 'purple', 'orange']}) # 1. 给每个ID下的行分配序号(从1开始,避免缺失值打乱计数) df['row_num'] = df.groupby('ID').cumcount() + 1 # 2. 透视转换,保留所有缺失值 pivoted_df = df.pivot(index='ID', columns='row_num') # 3. 重命名列:第一行序号(1)保留原名,后续行添加数字后缀 pivoted_df.columns = [f"{col}{num}" if num > 1 else col for col, num in pivoted_df.columns] # 4. 重置索引并调整列顺序,让输出结构和期望一致 result = pivoted_df.reset_index() # 按ID -> 第1组列 -> 第2组列 -> ... 的顺序排列 max_row_num = df['row_num'].max() sorted_columns = ['ID'] for num in range(1, max_row_num + 1): sorted_columns.extend([col for col in pivoted_df.columns if (str(num) in col) or (num == 1 and not col[-1].isdigit())]) result = result[sorted_columns] print(result)
输出效果
这段代码会生成和需求一致的结构,所有缺失值会保留为NaN(可根据需求用fillna('')替换为空字符串),例如:
| ID | Name | food | color | Name2 | food2 | color2 | Name3 | food3 | color3 |
|---|---|---|---|---|---|---|---|---|---|
| 1 | led | NaN | red | NaN | banana | pink | kent | banana | orange |
| 2 | peter | oranges | blue | make | carrots | NaN | NaN | NaN | NaN |
| 4 | NaN | carrots | red | NaN | NaN | NaN | NaN | NaN | NaN |
| 6 | levi | mango | purple | NaN | NaN | NaN | NaN | NaN | NaN |
内容的提问来源于stack exchange,提问作者Led
相关产品推荐
相关产品推荐

