python - 以最快的方式从数据框中删除值
问题描述
我有一个超过 500 万行的数据框。我还有一个要从数据框中删除的值列表。假设我的列表名称是a
,我的数据框名称是df
。下面是我用来检查 item ina
是否存在于的代码df
,然后将其从中删除df
:
if len(a) > 0:
for i in tqdm(a):
indexName = df[ df['id'] == i ].index
df.drop(indexName , inplace=True)
上面的代码需要 5 分钟。虽然它有效,但我很确定有一种更有效的方法。如果您有任何想法,请分享!
解决方案
for
循环调用df.drop
多次,效率不高。您可以使用Series.isin
.
考虑:
values_to_delete = [5, 6, 7]
df = pd.DataFrame({'a': [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]})
df.drop(df[df['a'].isin(values_to_delete)].index, inplace=True)
print(df)
输出
a
0 1
1 2
2 3
3 4
7 8
8 9
9 10
适应您的代码:
df.drop(df[df['id'].isin(tqdm(a))].index , inplace=True)
更快的替代方案
(见下面的时间)
可以为您想要的值过滤数据框,而不是删除您不想要的值:
df = df[~df['id'].isin(tqdm(a))] # note the ~ which acts as NOT operator
计时
from timeit import Timer
import numpy as np
values_to_delete = [5, 6, 7]
def create_df():
return pd.DataFrame({'a': np.random.randint(1, 10, 500000)})
def drop_loop():
df = create_df()
for i in values_to_delete:
indexName = df[df['a'] == i].index
df.drop(indexName, inplace=True)
def drop_single_call():
df = create_df()
df.drop(df[df['a'].isin(values_to_delete)].index, inplace=True)
def filtering():
df = create_df()
df[~df['a'].isin(values_to_delete)]
print(min(Timer(drop_loop).repeat(5, 5)))
print(min(Timer(drop_single_call).repeat(5, 5)))
print(min(Timer(filtering).repeat(5, 5)))
输出
1.0248285
0.5842238000000002
0.24234719999999932
(基本上)对于具有 500,000 行的示例数据帧,每种方法(OP、单次调用和过滤的丢弃)尝试 5 次。过滤方法通常快 75%。
推荐阅读
- c# - 在 ASP.NET Core 模块进程内托管 SetBasePath 中使用的目录
- c++ - 为什么我会收到 Wsign 转换警告?
- excel - Range.PasteSpecial 导致运行时错误“1004”
- android - E/FirebaseInstanceId:令牌检索失败:Android Kitkat 及以下版本中的 PHONE_REGISTRATION_ERROR
- salt-stack - Salt状态更改单个现有文件的权限
- botframework - Bot Framework ErrorResponseException:“'from'字段引用的机器人无法识别”
- google-compute-engine - 来自伊朗的 IP 地址在 Compute Engine 中被阻止
- python - Python pandas 定界符打印错误 - 双符号
- postgresql - postgres中的日志序列号真的单调吗?
- java - 与 VB.Net 中的 Now.ToString("yyyy-MM-dd") 等效的较短 Java 代码是什么?