如何高效过滤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
相关产品推荐
相关产品推荐

