希望加快循环,包括熊猫操作

时间:2017-11-30 19:54:15

标签: python performance pandas for-loop

我需要帮助加快这个循环,我不知道如何去做它

import numpy as np
import pandas as pd
import timeit

n = 1000
df = pd.DataFrame({0:np.random.rand(n),1:np.random.rand(n)})

def loop():
    result = pd.DataFrame(index=df.index,columns=['result'])
    for i in df.index:
        last_index_to_consider = df.index.values[::-1][i]
        tdf = df.loc[:last_index_to_consider] - df.shift(-i).loc[:last_index_to_consider]
        tdf = tdf.apply(lambda x: x**2)
        tsumdf = tdf.sum(axis=1)
        result.loc[i,'result'] = tsumdf.mean()
    return result

print(timeit.timeit(loop, number=10))

是否可以调整for循环以使其更快或是否有使用numba的选项,或者我可以继续使用多个线程来加速此循环吗?

获得更多性能的最明智的方法是什么才能直接评估此代码?

2 个答案:

答案 0 :(得分:3)

每次迭代都会发生很多计算。保持这种方式,我们可以利用基础数组数据和squared-sum-reductions def array_einsum_loop(df): a = df.values l = len(a) out = np.empty(l) for i in range(l): d = a[:l-i] - a[i:] out[i] = np.einsum('ij,ij->',d,d) df_out = pd.DataFrame({'result':out/np.arange(l,0,-1)}) return df_out 来实现加速。这是一个沿着这些方向实现的实现 -

In [153]: n = 1000
     ...: df = pd.DataFrame({0:np.random.rand(n),1:np.random.rand(n)})

In [154]: %timeit loop(df)
1 loop, best of 3: 1.43 s per loop

In [155]: %timeit array_einsum_loop(df)
100 loops, best of 3: 5.61 ms per loop

In [156]: 1430/5.61
Out[156]: 254.9019607843137

运行时测试 -

250x+

#define 加速而不会破坏任何循环或银行,这不错!

答案 1 :(得分:1)

只是为了好玩,numba的终极加速:

import numba
@numba.njit
def numba(d0,d1):
    n=len(d0)
    result=np.empty(n,np.float64)
    for i in range(n):
        s=0
        k=i
        for j in range(n-i):
            u = d0[j]-d0[k]
            v = d1[j]-d1[k]
            k+=1
            s += u*u + v*v    
        result[i] = s/(j+1) 
    return result

def loop2(df):
    return pd.DataFrame({'result':numba(*df.values.T)})

对于2500x +因子。

In [519]: %timeit loop2(df)
583 µs ± 5.87 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)