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

如何高效过滤DataFrame中指定重复值的最后一行?

高效过滤DataFrame中指定值的最后一行

需求与原实现

需求:过滤DataFrame中col1等于3的最后一行,保留其余数据并维持原有索引顺序。

原实现代码:

import pandas

d = {
     'col1': [0, 1, 2, 3, 3, 3, 3, 4, 5, 6],
     'col2': [0, 11, 21, 31, 32, 33, 34, 41, 51, 61]
    }

df = pandas.DataFrame(d)
df2 = df[df['col1'] != 3]
df3 = df[df['col1'] == 3].iloc[:-1]

pandas.concat([df2,df3]).sort_index()

执行结果:

col1  col2
0      0     0
1      1    11
2      2    21
3      3    31
4      3    32
5      3    33
7      4    41
8      5    51
9      6    61

原方法通过拆分、截取再合并排序实现需求,但在处理大数据帧时,数据拆分与合并的开销会显著增加,导致性能下降。

性能对比测试

针对1000万行的大数据帧,测试了多种实现方案的性能,测试代码如下:

import pandas
import random

dupes = 1000
rows = 10000000
d = {'col1': [random.choice(range(dupes)) for i in range(rows)], 'col2': [range for range in range(rows)]}
df = pandas.DataFrame(d)

# 原方法
df2 = df[df['col1'] != 3]
df3 = df[df['col1'] == 3].iloc[:-1]
%timeit pandas.concat([df2,df3]).sort_index()

# 方案2:通过last_valid_index定位后删除
df = pandas.DataFrame(d)
%timeit df.drop(df['col1'].where(df['col1'].eq(3)).last_valid_index())

# 方案3:倒序查找第一个等于3的索引后删除
df = pandas.DataFrame(d)
idx = df.loc[::-1, 'col1'].eq(3).idxmax()
%timeit df.drop(idx)

# 方案4:布尔索引直接筛选
df = pandas.DataFrame(d)
%timeit df.loc[ df["col1"].ne(3) | df["col1"].duplicated(keep="last") ]

# 方案5:获取所有等于3的索引后删除最后一个
df = pandas.DataFrame(d)
%timeit df.drop(df.index[df['col1'].eq(3)][-1])

# 方案6:倒序iloc查找第一个等于3的索引后删除
df = pandas.DataFrame(d)
%timeit df.drop((df['col1'].iloc[::-1] == 3).idxmax())

# 方案7:通过rank筛选
df = pandas.DataFrame(d)
%timeit df.loc[df['col1'].iloc[::-1].ne(3).rank(method = 'first').ne(1)]

# 方案8:通过索引切片删除最后一个等于3的行
df = pandas.DataFrame(d)
%timeit df.drop(index=df[df['col1'].eq(3)].index[-1:], axis=0)

测试结果(均值±标准差,7次运行,每次1循环):

原方法:703 ms ± 60.7 ms per loop
方案2:497 ms ± 10.9 ms per loop
方案3:413 ms ± 11.5 ms per loop
方案4:253 ms ± 6.7 ms per loop
方案5:408 ms ± 8.3 ms per loop
方案6:404 ms ± 8.02 ms per loop
方案7:792 ms ± 103 ms per loop
方案8:491 ms ± 142 ms per loop

最优方案推荐

从测试结果来看,方案4的性能最优,耗时仅为原方法的1/3左右。该方案通过布尔索引直接筛选满足条件的行:

  • df["col1"].ne(3):筛选所有col1不等于3的行
  • df["col1"].duplicated(keep="last"):筛选col1重复的行(去掉最后一个重复的3)
  • 两者通过|(或)逻辑合并,直接得到目标数据集,避免了数据拆分、合并和排序的开销,在大数据量下优势明显。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.28 20:15:06