2014-09-03 108 views
6

我试图有效地计算一个熊猫DataFrame的每列的指数衰减的运行总和。 DataFrame包含世界上每个国家的每日评分。数据框看起来是这样的:Python的指数衰减大熊猫DataFrame

   AF  UK  US 
2014-07-01 0.998042 0.595720 0.524698 
2014-07-02 0.380649 0.838436 0.355149 
2014-07-03 0.306240 0.274755 0.964524 
2014-07-04 0.396721 0.836027 0.225848 
2014-07-05 0.151291 0.677794 0.603548 
2014-07-06 0.558846 0.050535 0.551785 
2014-07-07 0.463514 0.552748 0.265537 
2014-07-08 0.240282 0.278825 0.116432 
2014-07-09 0.309446 0.096573 0.246021 
2014-07-10 0.800977 0.583496 0.713893 

我不知道如何计算的滚动总和(带衰减),而无需通过数据帧进行迭代,因为我需要知道昨天的成绩来计算今天的成绩。但是为了计算昨天的分数,我需要知道前天的分数等。这是我一直在使用的代码,但我想要一个更有效的方法来解决它。

for j, val in df.iteritems(): 
    for i, row in enumerate(val): 
     df[j].iloc[i] = row + val[i-1]*np.exp(-0.05) 

回答

8

您可以使用一个事实,即当指数乘以它们的指数增加:

如:

N(2) = N(2) + N(1) * exp(-0.05) 
N(3) = N(3) + (N(2) + N(1) * exp(-0.05))*exp(-0.05) 
N(3) = N(3) + N(2)*exp(-0.05) + N(1)*exp(-0.1) 
N(4) = ...and so on 

这可以被矢量使用numpy的:

dataset = pd.DataFrame(np.random.rand(1000,3), columns=["A", "B","C"]) 

weightspace = np.exp(np.linspace(len(dataset), 0, num=len(dataset))*-0.05) 
def rollingsum(array): 
    weights = weightspace[0-len(array):] 
    # Convolve the array and the weights to obtain the result 
    a = np.dot(array, weights).sum() 
    return a 


a = pd.expanding_apply(dataset, rollingsum) 

pd.expanding_apply适用rollingsum功能向后到每行,称它为len(dataset)次。 np.linspace生成一个大小为len(dataset)的数据集,并计算每行与当前行相乘的次数exp(-0.05)

由于是矢量,它应该是快:

%timeit a = pd.expanding_apply(dataset, rollingsum) 
10 loops, best of 3: 25.5 ms per loop 

与此相比,(注意:我使用Python 3中,不得不使第一行更改的行为...):

def multipleApply(df): 
    for j, val in df.iteritems(): 
     for i, row in enumerate(val): 
      if i == 0: 
       continue 
      df[j].iloc[i] = row + val[i-1]*np.exp(-0.05) 

这出来的:

In[68]: %timeit multipleApply(dataset) 
1 loops, best of 3: 414 ms per loop 
+0

@ZJS是什么呢? - 我将稍微修改一下,以便让它在python中工作3 – undershock 2014-09-03 18:38:07

+0

'%timeit t(df)' 100个循环,最好是3:每个循环3.96 ms – ZJS 2014-09-03 18:46:06

+0

@ZFS你是什么数据运行这个?编辑 – undershock 2014-09-03 18:46:52