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

如何在Pandas DataFrame中筛选col1/col2/col3同值、col4异值的行?有无更优方案?

问题:定位DataFrame中col1、col2、col3取值相同但col4取值不同的行

需求明确:在Pandas DataFrame内,筛选出col1、col2、col3三者取值完全一致,但col4取值存在差异的行;同时按col0分组后,每组内每个(col1, col2)组合只保留按col4排序后的第一行。

用户原始实现代码:

import pandas as pd
data = {
    'col0': ['A', 'A', 'A', 'B', 'B', 'C'],
    'col1': [1, 1, 1, 2, 2, 3],
    'col2': [1, 1, 1, 2, 2, 3],
    'col3': [1, 2, 3, 1, 2, 1],
    'col4': [10, 20, 30, 40, 50, 60]
}
df = pd.DataFrame(data)
df = df.sort_values(by='col4')
df['same_col1_col2'] = df.duplicated(subset=['col1', 'col2'], keep=False)
df['different_col3'] = df.groupby(['col1', 'col2'])['col3'].transform('nunique') > 1
df['final_flag'] = df['same_col1_col2'] & df['different_col3']
df_result = pd.DataFrame(columns=df.columns)
for symbol in df['col0'].unique():
    df_symbol = df[df['col0'] == symbol]
    df_filtered = df_symbol[df_symbol['final_flag']].drop_duplicates(subset=['col1', 'col2'], keep='first')
    df_result = pd.concat([df_result, df_filtered])
df_result = df_result.drop(columns=['same_col1_col2', 'different_col3', 'final_flag']).reset_index(drop=True)

print(df_result)
优化实现方案

可以通过更简洁的分组筛选逻辑实现,避免冗余列和循环拼接,提升代码可读性与执行效率:

import pandas as pd

data = {
    'col0': ['A', 'A', 'A', 'B', 'B', 'C'],
    'col1': [1, 1, 1, 2, 2, 3],
    'col2': [1, 1, 1, 2, 2, 3],
    'col3': [1, 2, 3, 1, 2, 1],
    'col4': [10, 20, 30, 40, 50, 60]
}
df = pd.DataFrame(data)

# 先按col4排序,确保后续取第一行的顺序符合需求
df_sorted = df.sort_values(by='col4')

# 核心逻辑:先筛选出(col1,col2,col3)相同但col4有不同值的行,再按(col0,col1,col2)分组取第一行
df_result = (
    df_sorted
    .groupby(['col1', 'col2', 'col3'])
    .filter(lambda group: group['col4'].nunique() > 1)
    .groupby(['col0', 'col1', 'col2'])
    .first()
    .reset_index()
)

print(df_result)

优化点说明

  • 移除冗余辅助列:无需创建same_col1_col2等中间列,直接通过groupby.filter完成目标分组筛选
  • 替换循环拼接:用Pandas链式调用替代for循环+pd.concat,代码更紧凑,大数据量下执行效率更高
  • 逻辑更直观:先锁定col1/col2/col3相同但col4不同的行,再按col0+col1+col2分组保留第一行,完全匹配需求

补充:若需求为「col1、col2相同,且组内存在col3相同但col4不同的行」

如果你的实际需求是同一(col1, col2)组内,存在部分col3相同但对应的col4不同的行,可调整筛选逻辑如下:

df_result = (
    df_sorted
    # 先筛选出(col1,col2)组内存在(col3相同但col4不同)的情况
    .groupby(['col1', 'col2'])
    .filter(lambda g: g.groupby('col3')['col4'].nunique().gt(1).any())
    # 按(col0,col1,col2)分组取第一行
    .groupby(['col0', 'col1', 'col2'])
    .first()
    .reset_index()
)

内容的提问来源于stack exchange,提问作者Alan Chau

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.22 21:35:02