我很惊讶地发现,在pandas中使用for循环和.head()
方法时,性能下降了多少。我正在寻找对我的问题的任何建议,我将在下面举例说明。在
import pandas as pd
import numpy as np
#create dictionary of 10000 dataframes
numdfs = 10000
alldf = {i:pd.DataFrame({'a':np.random.randn(250),'b':np.random.randn(250),'c':np.random.randn(250),'d':np.random.randn(250)}) for i in range(numdfs)}
count = 250
runningsum = 0
for i in range(numdfs):
df = alldf[i].head(count)
df['is negative'] = (df['b'] < 0).cummax().astype(int)
runningsum += df['is negative'].max()
上面的代码在我的机器上执行大约需要15分钟,而在for循环使其在一分钟内执行之后,从第一行删除.head(count)
!在
有人能谈谈为什么会这样,以及我如何提高绩效吗?之所以使用.head(),是因为在实际示例中,我希望对条件求值,直到数据帧中可能有不同数量的样本
(df['b'] < 0).cummax().astype(int).max()
只检查是否有值 小于0。您可以改为使用(df['b'] < 0).any()
。有 也不需要int
转换,因为考虑了布尔值1
/0
分别为True
/False
。在顺便说一句,
loc
/iloc
往往比其他形式的切片更有效,但这并不是导致性能差的主要原因,尽管您进行了测试。在对于等效算法,可以使用带
sum
的生成器表达式:以下是一些性能基准:
^{pr2}$该算法仍然相当慢,因为如果发现小于零的值可能会短路,则不必要地检查
'b'
中的每个单个值。使用numba
可以实现一种循环方式,它比原始算法提高了~12000x倍对于10000个数据帧,就像在您的测试中一样,这将在不到一秒钟的时间内起作用:
相关问题 更多 >
编程相关推荐