【发布时间】:2019-06-26 07:07:08
【问题描述】:
如何优化获取和设置条件复杂的数据帧更新速度?
以下方法(使用.loc[])似乎效率很低:
import pandas as pd
import numpy as np
df = pd.DataFrame({'a': [0,0,0,0,1,3,1],
'b': [0,2,0,0,4,1,1],
'c': [0,0,0,0,1,1,1]})
# GET conditions
np.where(((df['a']==1)&(df['b']==df['a'])))
# SET conditions
np.where(((df['a']==0)&(df['b']>1)))
# Applying GET & SET conditions in update (using .loc[])- 3ms
df.loc[((df['a'] == 0)&(df['b']>1))] = df.loc[((df['a']==1)&(df['b']==df['a']))]
我可以在保留这两个选择/更新条件的同时使用 df.values 和 numpy 降低执行时间吗?
更新
使用 jpp 的答案(将 df.values 导入 numpy 并使用掩码进行选择/更新),该操作的运行速度提高了约 5,500 倍。
【问题讨论】:
-
我相信您需要分配
df.loc[((df['a']==1)&(df['b']==df['a']))].values(注意末尾的.values)才能使您的示例正常工作。 -
运行该行:
df.loc[((df['a'] == 0)&(df['b']>1))] = df.loc[((df['a']==1)&(df['b']==df['a']))].values产生输出:ValueError: cannot set using a list-like indexer with a different length than the value -
好的,你的示例数据对我有用。但很高兴使用 NumPy 解决了您的性能问题。
-
啊,只有当我在包括
.values在内的行上使用%timeit时才产生ValueError。删除它工作正常。使用time.time(),df.loc[((df['a'] == 0)&(df['b']>1))] = df.loc[((df['a']==1)&(df['b']==df['a']))].values行似乎与问题中的原始行具有相同的执行时间。
标签: python pandas performance numpy dataframe