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

如何基于两个条件删除DataFrame分组中不需要的行?

高效处理DataFrame分组过滤需求

输入数据

import pandas as pd

df = pd.DataFrame({'col1': ['A', 'A', 'B', 'C', 'D', 'D', 'D', 'E', 'E'],
 'col2': ['x1', 'x2', 'x1', 'x1', 'x1', 'x2', 'x3', 'x1', 'x2'],
 'col3': ['', 'mssg1', 'mssg2', '', 'mssg3', '', 'mssg4', '', '']})

需求说明

按col1分组后执行如下过滤规则:

  • 若分组内有多行,且存在col3非空的行:仅保留col3非空的行
  • 若分组内所有行col3都为空:保留分组内所有行
  • 若分组只有一行:直接保留该行

原始代码的问题

你当前的apply逐组处理方式在大数据集上效率极低,因为apply本质是循环操作,无法利用pandas的矢量化优化。另外,replace('', None)再fillna('')的操作也存在冗余。

优化解决方案

用矢量化操作替代逐组循环,全程利用pandas的内置函数实现高效计算:

# 1. 标记col3是否非空(空字符串视为空)
df['col3_non_empty'] = df['col3'] != ''

# 2. 计算每个col1分组的两个关键指标:分组大小、是否存在非空col3
group_info = df.groupby('col1').agg(
    group_size=('col1', 'size'),
    has_non_empty=('col3_non_empty', 'any')
).reset_index()

# 3. 将分组指标合并回原DataFrame
df_with_group = df.merge(group_info, on='col1')

# 4. 生成过滤条件
filter_condition = (
    # 分组只有一行,直接保留
    (df_with_group['group_size'] == 1)
    # 分组全为空,保留所有行
    | (~df_with_group['has_non_empty'])
    # 分组有多行且存在非空,保留当前行col3非空的
    | (df_with_group['col3_non_empty'])
)

# 5. 过滤并清理临时列
final = df_with_group[filter_condition].drop(columns=['col3_non_empty', 'group_size', 'has_non_empty'])

验证结果

执行后得到的final输出与期望完全一致:

col1 col2   col3
1    A   x2  mssg1
2    B   x1  mssg2
3    C   x1       
4    D   x1  mssg3
6    D   x3  mssg4
7    E   x1       
8    E   x2       

效率说明

这种方案全程使用pandas的矢量化聚合、合并操作,避免了逐组循环,在大数据集上的运行效率比apply版本提升数倍甚至数十倍,同时逻辑清晰无遗漏,完全覆盖所有规则场景。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.04 18:10:14