使用Pandas内连接合并两个DataFrame后如何去除重复行?
解决Pandas Merge后行数异常膨胀的问题
你的问题核心是连接键在两个DataFrame中存在重复组合,导致inner join时产生笛卡尔积,最终行数暴增。以下是分步解决方法:
1. 定位重复的连接键组合
先明确是哪个DataFrame的连接键存在重复,以及重复的程度:
import pandas as pd # 检查df_1中(H0002, H0003)的重复情况 df1_dup_counts = df_1.groupby(['H0002', 'H0003']).size().reset_index(name='row_count') df1_duplicates = df1_dup_counts[df1_dup_counts['row_count'] > 1] print(f"df_1中有 {len(df1_duplicates)} 组重复的连接键") # 检查df_2中(ordrenr, radnr)的重复情况 df2_dup_counts = df_2.groupby(['ordrenr', 'radnr']).size().reset_index(name='row_count') df2_duplicates = df2_dup_counts[df2_dup_counts['row_count'] > 1] print(f"df_2中有 {len(df2_duplicates)} 组重复的连接键")
2. 根据业务逻辑清洗重复数据
情况1:重复行是完全冗余的(所有列值都相同)
直接保留每个连接键组合的第一行即可:
# 清洗df_1 df_1_clean = df_1.drop_duplicates(subset=['H0002', 'H0003'], keep='first') # 清洗df_2 df_2_clean = df_2.drop_duplicates(subset=['ordrenr', 'radnr'], keep='first')
情况2:重复行包含不同业务数据(需要聚合)
如果重复行的其他列有差异,要根据业务规则聚合,比如取数值列的均值、非数值列的第一个值:
# 为df_1定义聚合规则:数值列取均值,其他列取第一个值 agg_rules_df1 = {} for col in df_1.columns: if col not in ['H0002', 'H0003']: if df_1[col].dtype in ['int64', 'float64']: agg_rules_df1[col] = 'mean' else: agg_rules_df1[col] = 'first' df_1_agg = df_1.groupby(['H0002', 'H0003']).agg(agg_rules_df1).reset_index() # 同理处理df_2 agg_rules_df2 = {} for col in df_2.columns: if col not in ['ordrenr', 'radnr']: if df_2[col].dtype in ['int64', 'float64']: agg_rules_df2[col] = 'mean' else: agg_rules_df2[col] = 'first' df_2_agg = df_2.groupby(['ordrenr', 'radnr']).agg(agg_rules_df2).reset_index()
3. 执行合并
用清洗后的DataFrame进行inner join:
# 用去重后的df合并 merged_df = pd.merge( df_1_clean, df_2_clean, left_on=['H0002', 'H0003'], right_on=['ordrenr', 'radnr'], how='inner' ) # 或者用聚合后的df合并 # merged_df = pd.merge( # df_1_agg, # df_2_agg, # left_on=['H0002', 'H0003'], # right_on=['ordrenr', 'radnr'], # how='inner' # )
4. 验证结果
合并后行数应该等于两个DataFrame中唯一连接键组合的交集数量,可以用以下代码确认:
# 计算df_1的唯一连接键数量 unique_df1 = len(df_1_clean[['H0002', 'H0003']].drop_duplicates()) # 计算df_2的唯一连接键数量 unique_df2 = len(df_2_clean[['ordrenr', 'radnr']].drop_duplicates()) # 计算交集数量 common_keys = pd.merge( df_1_clean[['H0002', 'H0003']].drop_duplicates(), df_2_clean[['ordrenr', 'radnr']].drop_duplicates(), left_on=['H0002', 'H0003'], right_on=['ordrenr', 'radnr'] ) print(f"预期合并行数:{len(common_keys)}") print(f"实际合并行数:{len(merged_df)}")
内容的提问来源于stack exchange,提问作者user17637519
相关产品推荐
相关产品推荐

