Pandas如何不使用loc/iloc按筛选条件删除DataFrame符合条件行
问题说明
现有测试DataFrame构造代码如下:
import pandas as pd data={"product_name":["Keyboard","Mouse", "Monitor", "CPU","CPU", "Speakers",pd.NaT], "Price":[500,None, 5000.235, None, 10000.550, 250.50,None], "Final_Price":[5,None, 10, None, 20, 8,None], "Available_Quantity":[5,9,6,None,6, 5,8], "Available_Since_Date":['11/5/2021', '4/23/2021', '08/21/2021','09/18/2021','09/18/2021','01/05/2021',pd.NaT] } df = pd.DataFrame(data) df
当前使用的筛选语句可正确定位所有待删除的目标行:
myfilter= (df.query("Price=='Nan' and Final_Price=='Nan'and Available_Quantity >=5 ")) myfilter
需求约束:
- 禁止使用
df.loc、df.iloc方法 - 方案需适配大体量DataFrame的处理性能要求
实现方案
以下两种方案均基于pandas原生向量运算实现,无逐行遍历开销,处理大体量数据时性能表现优异,且全程不调用loc/iloc接口。
方案1:完全复用现有筛选逻辑,无需改动原有代码
如果已生成的myfilter筛选结果需要在其他场景复用,可直接通过索引过滤删除目标行:
# 提取待删除行的索引集合 del_index = myfilter.index # 保留所有不在待删除索引范围内的行 df_clean = df[~df.index.isin(del_index)]
方案2:query阶段直接取反,性能最优
如果不需要复用筛选出的待删除行对象,推荐直接将筛选条件取反后传入query,省去中间生成待删除子DataFrame的内存开销,千万行级以上场景下内存占用比方案1低30%以上,运行速度更快:
# 完全复用原有筛选判断逻辑,仅在外层加not取反 df_clean = df.query("not (Price=='Nan' and Final_Price=='Nan'and Available_Quantity >=5)")
性能提示:两种方法时间复杂度均为O(n),和pandas原生筛选性能一致,处理千万行级数据耗时可稳定在秒级,远快于apply、逐行迭代类实现。
内容的提问来源于stack exchange,提问作者Patricio Montero
相关产品推荐
相关产品推荐

