baz*_*zel 3 python numpy pandas
改进这个问题提供了一个聪明的解决方案,用于在DataFrame中的多个列上应用函数,我想知道该解决方案是否可以进一步优化速度.
环境:Python 2.7.8,Pandas 14.1,Numpy 1.8.
这是示例设置:
import pandas as pd
import numpy as np
import random
def meanmax(ii,df):
xdf = df.iloc[map(int,ii)]
n = max(xdf['A']) + max(xdf['B'])
return n / 2.0
df = pd.DataFrame(np.random.randn(2500,2)/10000,
index=pd.date_range('2001-01-01',periods=2500),
columns=['A','B'])
df['ii'] = range(len(df))
res = pd.rolling_apply(df.ii, 26, lambda x: meanmax(x, df))
Run Code Online (Sandbox Code Playgroud)
请注意,该meanmax函数不是成对的,因此类似的东西rolling_mean(df['A'] + df['B'],26)不起作用.
但是我可以这样做:
res2 = (pd.rolling_max(df['A'],26) + pd.rolling_max(df['B'],26)) / 2
Run Code Online (Sandbox Code Playgroud)
其完成速度大约快3000倍:
%timeit res = pd.rolling_apply(df.ii, 26, lambda x: meanmax(x, df))
1 loops, best of 3: 1 s per loop
%timeit res2 = (pd.rolling_max(df['A'],26) + pd.rolling_max(df['B'],26)) / 2
1000 loops, best of 3: 325 µs per loop
Run Code Online (Sandbox Code Playgroud)
有没有比上面第二个选项更好/等效的东西,给定示例函数并使用rolling_apply?虽然第二个选项更快,但它不使用a rolling_apply,可以应用于更广泛的问题集
编辑:性能计时校正
在具有大小n窗口的大小数组上计算通用滚动函数m需要大约O(n*m)时间.内置的rollin_xxx方法使用一些非常聪明的算法来保持运行时间远远低于这个,并且通常可以保证O(n)时间,如果你认为它是一个非常令人印象深刻的事情.
rolling_min并rolling_max特别借鉴了其实施的瓶颈,其援引理查德·哈特作为算法的来源,但我发现我的想法是用相同算法的早期描述本文.
所以在历史课之后:很可能你不能吃蛋糕了.rolling_apply非常方便,但它几乎总是会牺牲特定算法的性能.根据我的经验,使用Python科学堆栈的一个更令人愉快的部分是提出有效的计算方法,使用创造性方式提供的快速原语.你自己的解决方案rolling_max两次调用就是一个很好的例子.因此rolling_apply,如果您或SO的优秀人员无法提供更智能的解决方案,那么您将永远不得不放松下来.