You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

基于id与ticker组合识别DataFrame重复项并按条件过滤处理

解决DataFrame中(id,ticker)重复项的展示与过滤删除问题

嘿,我明白你想要的是先找出所有id和ticker组合的重复行,再通过过滤的方式(而非排序)根据state列的条件清理重复项,这就来一步步帮你实现:

第一步:展示所有(id,ticker)组合的重复项

我们可以用duplicated()方法,指定检查重复的列是id和ticker,并设置keep=False来获取所有重复的行(包括第一次出现的重复行):

# 筛选并展示所有id与ticker组合的重复行
duplicate_entries = df[df.duplicated(subset=['id', 'ticker'], keep=False)]
display(duplicate_entries)

运行这段代码后,你就能看到所有存在重复(id,ticker)组合的行,比如你数据里的396496和396588相关的行都会被列出来。

第二步:通过过滤方式删除不符合条件的重复项

这里关键是先明确你的state保留规则,比如:

  • 对于重复的(id,ticker)组合,优先保留state="Done"的行
  • 如果没有Done状态,就保留非NULL的行
  • 如果同组内都是相同的有效state(比如你的396588两行都是Order Sent),可以选择全部保留或只留一行(根据你的需求调整)

方案1:用groupby+自定义过滤函数

这种方式直接按分组过滤,逻辑清晰:

def filter_group(group):
    # 优先保留state为Done的行
    if 'Done' in group['state'].values:
        return group[group['state'] == 'Done']
    # 没有Done的话,排除NULL的行
    else:
        return group[group['state'] != 'NULL']

# 按id和ticker分组,应用过滤函数,合并结果
cleaned_df = df.groupby(['id', 'ticker'], group_keys=False).apply(filter_group)
display(cleaned_df)

针对你的示例数据,这段代码会保留396496对应的Done行,排除NULL行;而396588的两行都是Order Sent,会全部保留(如果想每个组合只留一行,可以在最后加上.drop_duplicates(subset=['id','ticker'], keep='first'))。

方案2:用transform标记保留行再过滤

如果你更喜欢用列标记的方式,也可以这样做:

# 给每行标记是否需要保留
df['to_keep'] = df.groupby(['id', 'ticker'])['state'].transform(
    lambda x: x == 'Done' if 'Done' in x.values else x != 'NULL'
)

# 过滤出需要保留的行,删除标记列
cleaned_df = df[df['to_keep']].drop('to_keep', axis=1)
display(cleaned_df)

这个方案的效果和方案1完全一致,只是实现方式不同,都是纯过滤逻辑,没有依赖排序操作。


内容的提问来源于stack exchange,提问作者Peter Lucas

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.25 08:22:09