python-3.x 在Pandas DataFrame上应用带参数的自定义滚动函数

dgsult0t  于 2022-12-15  发布在  Python
关注(0)|答案(1)|浏览(155)

我有这个df(这里是df.head()):

date        colA
0   2018-01-05  0.6191
1   2018-01-20  0.5645
2   2018-01-25  0.5641
3   2018-01-27  0.5404
4   2018-01-30  0.4933

我想对每3行递归地应用一个函数,这意味着对于行:1、2、3,则对于行:2、3、4,然后是行3、4、5等。
这是我写的

def my_rolling_func(df, val):
  
    p1 = (df['date']-df['date'].min()).dt.days.tolist()[0],df[val].tolist()[0]
    p2 = (df['date']-df['date'].min()).dt.days.tolist()[1],df[val].tolist()[1]
    p3 = (df['date']-df['date'].min()).dt.days.tolist()[2],df[val].tolist()[2]
  
    return sum([i*j for i,j in [p1,p2,p3]])

df.rolling(3,center=False,axis=1).apply(my_rolling_func, args=('colA'))

但我得到这个错误:
ValueError:传递值的长度为1,索引表示494。
494是我的df中的行数。
我不知道为什么它说我传递了一个长度为1的函数,我认为滚动会根据我定义的窗口大小生成df的切片(3),然后它对df的子集应用该函数。

xdyibdwo

xdyibdwo1#

首先,您指定了错误的轴。轴1意味着窗口将沿着列滑动。您希望窗口沿着索引滑动,因此需要指定axis=0。其次,您对滚动的工作原理有一点误解。它将把您的函数独立地应用于每一列。所以你不能在你的函数中同时对datecolA列进行操作。我重写了你的代码来使它工作:

import pandas as pd
import numpy as np

df = pd.DataFrame({'date':pd.date_range('2018-01-05', '2018-01-30', freq='D'), 'A': np.random.random((26,))})
df = df.set_index('date')

def my_rolling_func(s):
    days = (s.index - s.index[0]).days
    return sum(s*days)

res = df.rolling(3, center=False, axis=0).apply(my_rolling_func)

print(res)
Out: 
                  A
date                
2018-01-05       NaN
2018-01-06       NaN
2018-01-07  1.123872
2018-01-08  1.121119
2018-01-09  1.782860
2018-01-10  0.900717
2018-01-11  0.999509
2018-01-12  1.755408
2018-01-13  2.344914
       .....

相关问题