将自定义功能应用于滚动数据框

时间:2020-10-10 09:25:52

标签: pandas dataframe

我有一个函数(我们称它为RBSA(df))(我目前将该函数视为黑匣子),该函数需要一个数据帧

   DATE      RETURN    STYLE1    STYLE2    STYLE3    STYLE4
2020-09-01    0.01      100       251       300       211
2020-09-02    0.04      106       248       310       210
2020-09-03    0.03      104       251       308       211
2020-09-03    0.02      110       258       306       212
...

并返回这样的数据框

DATE       STYLE1    STYLE2    STYLE3    STYLE4    R2
2020        0.01      85        10        4.99     68

现在,我希望能够以30为窗口的滚动方式将该功能应用于初始数据库,以使数据框看起来像这样。

  DATE       STYLE1    STYLE2    STYLE3    STYLE4    R2
2020-09       0.01      85        10        4.99     68   #applied date range would be 09-01 to 09-30
2020-09       0.99      80        15        4.01     77   #applied date range would be 09-02 to 10-01
2020-09       3.93      80        10        6.07     89   #applied date range would be 09-03 to 10-02

到目前为止,我已经尝试使用df.rolling(30).apply(RBSA),但是据我所知,rolling.apply函数通过将每个窗口变成numpy.ndarray来应用该函数。但是,由于我将RBSA()函数视为黑匣子,因此我宁愿不更改RBSA()函数使其具有numpy.ndarray作为输入。

我的第二个想法是创建一个for循环,将每个数据帧append()转换为最初为空的数据帧。但是,我不太确定如何使用while循环来模拟滚动窗口。

def rolling30(df):
   count = len(count) - 30
   ret = []
   while (count > 0):
      count = count - 1
      df2 = df[count:count + 30]
      df2 = style(df2)
      ret.append(df2)

但是,与将数据帧手动附加到一起不同,由于某种原因,当我将数据帧附加到一起时,它似乎创建了一个看起来像这样的输出(请注意逗号)

  DATE       STYLE1    STYLE2    STYLE3    STYLE4    R2
2020-09       0.01      85        10        4.99     68, DATE       STYLE1    STYLE2    STYLE3    STYLE4    R2  
2020-09       0.99      80        15        4.01     77, DATE       STYLE1    STYLE2    STYLE3    STYLE4    R2   
2020-09       3.93      80        10        6.07     89, DATE       STYLE1    STYLE2    STYLE3    STYLE4    R2   

现在,在使用while循环解决方案时,感觉就像我离得最近。尽管感觉不如使用rolling.apply

优雅

更新:只做了一个isinstance(rolling30(df), pd.DataFrame)并返回了False,所以我认为问题在于某处将其还原为非数据帧。

1 个答案:

答案 0 :(得分:0)

因此,我想出了while循环探针的解决方案。意识到最初的ret是一个列表,并将其更改为ret = pd.DataFrame(),然后将其追加以回调到ret

def rolling30(df):
   count = len(count) - 30
   ret = pd.DataFrame()
   while (count > 0):
      count = count - 1
      df2 = df[count:count + 30]
      df2 = style(df2)
      ret = ret.append(df2)

我仍然想看看其他人对这个问题有什么方法,因为我觉得在这里部署While循环并不是一个很好的解决方案。