Pandas筛选含指定code的重复join key行并合并数据
解决DataFrame筛选同时包含特定code的分组并合并行的问题
看起来你现在的核心问题是没能精准筛选出同时包含code=521和code=539的join key分组,反而把那些只有重复521的分组也拉进来了对吧?咱们一步步来修正这个逻辑:
问题根源
你当前的代码先通过duplicated(['join key'], keep=False)选出所有有重复join key的行,再过滤code为521/539,但这会把像3509730366这种只有多个521、完全没有539的分组也保留下来——这就是你说的“总是选中仅同code的重复join key行”的原因。
解决方案步骤
我们需要先筛选出每个join key分组里同时包含521和539这两个code值的分组,再对这些分组进行行合并操作:
1. 先缩小范围:只保留code为521或539的行
这一步是可选的,但能减少后续处理的数据量:
filtered_df = exp_csv[exp_csv['code'].isin([521, 539])]
2. 筛选出同时包含两个code的join key分组
我们可以通过分组后检查每个分组的code集合是否包含{521,539}来实现:
# 先获取符合条件的join key列表 valid_join_keys = filtered_df.groupby('join key')['code'].apply(lambda x: {521, 539}.issubset(x)).loc[lambda x: x].index # 用这个列表过滤出目标行 target_df = filtered_df[filtered_df['join key'].isin(valid_join_keys)]
3. 实现行合并逻辑(对应你的compute(x)函数)
接下来对每个符合条件的分组,把code=521的A、B列和code=539的C、D列合并成一行。这里我们可以直接在apply里实现逻辑,或者单独写compute函数:
def compute(group): # 取出code=521的行(假设每个分组里521和539各至少一行,若有多个可按需取第一个或聚合) row_521 = group[group['code'] == 521].iloc[0] # 取出code=539的行 row_539 = group[group['code'] == 539].iloc[0] # 合并需要的列 merged_row = { 'join key': row_521['join key'], 'A': row_521['A'], 'B': row_521['B'], 'C': row_539['C'], 'D': row_539['D'] } return pd.Series(merged_row) # 应用函数并整理结果 result = target_df.groupby('join key').apply(compute).reset_index(drop=True)
完整测试代码
把所有步骤整合起来,用你的测试数据验证:
import pandas as pd # 测试数据 exp_csv = pd.DataFrame([ [3566190983, 521, 1, 2, 3, 4], [3566190983, 539, 1, 2, 3, 4], [3509730366, 521, 1, 2, 3, 4], [3509730366, 521, 1, 2, 3, 4], [3509730366, 521, 1, 2, 3, 4], [9809730686, 500, 1, 2, 3, 4] ], columns=['join key', 'code', 'A', 'B', 'C', 'D']) def compute(group): row_521 = group[group['code'] == 521].iloc[0] row_539 = group[group['code'] == 539].iloc[0] merged_row = { 'join key': row_521['join key'], 'A': row_521['A'], 'B': row_521['B'], 'C': row_539['C'], 'D': row_539['D'] } return pd.Series(merged_row) # 执行流程 filtered_df = exp_csv[exp_csv['code'].isin([521, 539])] valid_join_keys = filtered_df.groupby('join key')['code'].apply(lambda x: {521, 539}.issubset(x)).loc[lambda x: x].index target_df = filtered_df[filtered_df['join key'].isin(valid_join_keys)] result = target_df.groupby('join key').apply(compute).reset_index(drop=True) print(result)
运行后会得到预期的结果:
join key A B C D 0 3566190983 1 2 3 4
这样就精准筛选出了同时包含521和539的分组,并且完成了行合并操作。如果你的实际数据中每个分组里521或539有多个行,可以根据需求调整iloc[0]为聚合操作(比如取均值、求和等)。
内容的提问来源于stack exchange,提问作者Indaco789
相关产品推荐
相关产品推荐

