如何使用Pandas实现对应分组行的合并及Val比值列生成
Pandas DataFrame重构:合并分组并计算比值
没问题,这个需求其实可以通过Pandas的拆分、合并和列处理轻松实现,我给你一步步拆解操作:
步骤1:拆分Flag为A和B的两组数据
首先把原始数据按Flag拆分成两个独立的DataFrame,同时删掉不需要的Flag列,给可能存在差异的列加上分组后缀避免后续冲突:
import pandas as pd # 假设原始数据存储在df中 df_a = df[df['Flag'] == 'A'].drop('Flag', axis=1).rename( columns=lambda x: x + '_A' if x not in ['Attr1', 'AttrN'] else x ) df_b = df[df['Flag'] == 'B'].drop('Flag', axis=1).rename( columns=lambda x: x + '_B' if x not in ['Attr1', 'AttrN'] else x )
这里的重命名逻辑是:除了确认无差异的公共列(比如Attr1、AttrN),其他可能有差异的列(比如Attr2)分别加上_A/_B后缀,确保合并时列名不重复。
步骤2:按Attr1合并两组数据
因为每个A组行都有对应的B组行,用Attr1做内连接就能精准匹配对应记录:
merged_df = pd.merge(df_a, df_b, on='Attr1', how='inner')
步骤3:计算Val的比值列
新增Val_A/B列,用A组的Val值除以B组的Val值:
merged_df['Val_A/B'] = merged_df['Val_A'] / merged_df['Val_B']
如果担心出现除零错误,可以改用更安全的除法方法:
merged_df['Val_A/B'] = merged_df['Val_A'].div(merged_df['Val_B'], fill_value=0)
步骤4:整理最终列顺序(可选)
如果需要和目标格式完全一致的列顺序,手动调整即可:
final_columns = ['Attr1', 'Attr2_A', 'Attr2_B', 'AttrN', 'Val_A/B'] final_df = merged_df[final_columns]
完整示例代码
把以上步骤整合,针对你的示例数据测试:
import pandas as pd # 构造示例数据 data = { 'Attr1': ['a1', 'a2', 'a1', 'a2'], 'Attr2': ['b1.1', 'b2.1', 'b1.2', 'b2.2'], 'AttrN': ['N1', 'N2', 'N1', 'N2'], 'Val': [100, 200, 20, 50], 'Flag': ['A', 'A', 'B', 'B'] } df = pd.DataFrame(data) # 拆分并重命名 df_a = df[df['Flag'] == 'A'].drop('Flag', axis=1).rename( columns=lambda x: x + '_A' if x not in ['Attr1', 'AttrN'] else x ) df_b = df[df['Flag'] == 'B'].drop('Flag', axis=1).rename( columns=lambda x: x + '_B' if x not in ['Attr1', 'AttrN'] else x ) # 合并数据 merged_df = pd.merge(df_a, df_b, on='Attr1', how='inner') # 计算比值 merged_df['Val_A/B'] = merged_df['Val_A'] / merged_df['Val_B'] # 调整列顺序 final_columns = ['Attr1', 'Attr2_A', 'Attr2_B', 'AttrN', 'Val_A/B'] final_df = merged_df[final_columns] print(final_df)
运行后会输出你想要的结果:
Attr1 Attr2_A Attr2_B AttrN Val_A/B 0 a1 b1.1 b1.2 N1 5.0 1 a2 b2.1 b2.2 N2 4.0
补充说明
如果你的公共属性列不止Attr1和AttrN,只需要在重命名时把这些列加入到排除列表里即可;如果有更多类似Attr2的差异列,代码会自动给它们加上分组后缀,无需额外修改。
内容的提问来源于stack exchange,提问作者Seriously
相关产品推荐
相关产品推荐

