python - Pandas 适用于多列输出滚动

标签 python pandas dataframe rolling-computation

我正在编写将滚动窗口应用于将返回多列的函数的代码。
输入: Pandas 系列
预期输出:3 列 DataFrame

def fun1(series, ):
    # Some calculations producing numbers a, b and c
    return {"a": a, "b": b, "c": c} 

res.rolling('21 D').apply(fun1)
资源内容:
time
2019-09-26 16:00:00    0.674969
2019-09-26 16:15:00    0.249569
2019-09-26 16:30:00   -0.529949
2019-09-26 16:45:00   -0.247077
2019-09-26 17:00:00    0.390827
                         ...   
2019-10-17 22:45:00    0.232998
2019-10-17 23:00:00    0.590827
2019-10-17 23:15:00    0.768991
2019-10-17 23:30:00    0.142661
2019-10-17 23:45:00   -0.555284
Length: 1830, dtype: float64
错误:
TypeError: must be real number, not dict
我试过的:
  • 在应用中更改 raw=True
  • 在应用中使用 lambda 函数
  • 将 fun1 中的结果作为列表/numpy 数组/数据帧/系列返回。

  • 我还在 SO 中浏览了许多相关帖子,以说明以下几点:
  • Pandas - Using `.rolling()` on multiple columns
  • Returning two values from pandas.rolling_apply
  • How to apply a function to two columns of Pandas dataframe
  • Apply pandas function to column to create multiple new columns?

  • 但是指定的解决方案都没有解决这个问题。
    有没有直接的解决方案?

    最佳答案

    这是一个 哈奇 回答使用 rolling ,产生一个数据帧:

    import pandas as pd
    import numpy as np
    
    dr = pd.date_range('09-26-2019', '10-17-2019', freq='15T')
    data = np.random.rand(len(dr))
    
    s = pd.Series(data, index=dr)
    
    output = pd.DataFrame(columns=['a','b','c'])
    
    row = 0
    
    def compute(window, df):
        global row
        a = window.max()
        b = window.min()
        c = a - b
        df.loc[row,['a','b','c']] = [a,b,c]
        row+=1    
        return 1
        
    s.rolling('1D').apply(compute,kwargs={'df':output})
    
    output.index = s.index
    
    好像是rolling apply函数总是期望返回一个数字,以便根据计算立即生成一个新的系列。
    我通过制作一个新的 output 来解决这个问题DataFrame(带有所需的输出列),并在函数内写入该列。我不确定是否有办法在滚动对象中获取索引,所以我改为使用 global增加写入新行的次数。不过,鉴于上述观点,您需要 return一些数字。所以虽然实际上 rolling操作返回一系列 1 , output被修改:
    In[0]:
    s
    
    Out[0]:
    2019-09-26 00:00:00    0.106208
    2019-09-26 00:15:00    0.979709
    2019-09-26 00:30:00    0.748573
    2019-09-26 00:45:00    0.702593
    2019-09-26 01:00:00    0.617028
      
    2019-10-16 23:00:00    0.742230
    2019-10-16 23:15:00    0.729797
    2019-10-16 23:30:00    0.094662
    2019-10-16 23:45:00    0.967469
    2019-10-17 00:00:00    0.455361
    Freq: 15T, Length: 2017, dtype: float64
    
    In[1]:
    output
    
    Out[1]:
                               a         b         c
    2019-09-26 00:00:00  0.106208  0.106208  0.000000
    2019-09-26 00:15:00  0.979709  0.106208  0.873501
    2019-09-26 00:30:00  0.979709  0.106208  0.873501
    2019-09-26 00:45:00  0.979709  0.106208  0.873501
    2019-09-26 01:00:00  0.979709  0.106208  0.873501
                          ...       ...       ...
    2019-10-16 23:00:00  0.980544  0.022601  0.957943
    2019-10-16 23:15:00  0.980544  0.022601  0.957943
    2019-10-16 23:30:00  0.980544  0.022601  0.957943
    2019-10-16 23:45:00  0.980544  0.022601  0.957943
    2019-10-17 00:00:00  0.980544  0.022601  0.957943
    
    [2017 rows x 3 columns]
    
    这感觉更像是对 rolling 的一种利用比预期用途,所以我有兴趣看到一个更优雅的答案。
    更新 : 感谢@JuanPi,您可以使用 this answer 获取滚动窗口索引.所以一个非 global答案可能如下所示:
    def compute(window, df):
        a = window.max()
        b = window.min()
        c = a - b
        df.loc[window.index.max(),['a','b','c']] = [a,b,c]  
        return 1
    

    关于python - Pandas 适用于多列输出滚动,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62716558/

    相关文章:

    python - Pandas :Groupby,连接一列并确定具有最大值的行

    python - 按条件查找dataframe中行和列的所有索引

    python - 用 NA 值填充 dict 以允许转换为 pandas 数据帧

    python - python中的neomodel如何在没有数据库名称的情况下连接neo4j db?

    python - 使用 "pointer"更新 tkinter 小部件参数

    python - 如何使用 Python 将字符串中的特定字符序列转换为大写?

    python - 如何在不使用循环的情况下使用自己的度量创建距离矩阵?

    python - Pandas 中双括号 `[[...]]` 和单括号 `[..]` 索引之间的区别

    python - 如何删除python中单元格中包含 'Unnamed'的行?

    python - 如果列存在于 df 中,如何根据条件删除 Pandas 中的列数据框 (df)?