【问题标题】:Issues using the rolling feature of pandas with a condition使用带有条件的熊猫滚动功能的问题
【发布时间】:2021-10-31 08:39:35
【问题描述】:

我尝试使用rolling(4).sum().shift(-3) 但我遇到了一个不断添加的问题,因为我没有停止检查运动是否发生变化的条件。我尝试了 groupby ,但它也会引发错误。有什么建议吗?

movement value
right 2
right 1
right 3
right 1
right 1
right 1
right 1
right 1
Left 5
Left 4
Left 2
Left 1
Left 1
Left 1
Left 1
Left 1

我想要得到的是以下内容:

movement value rolling value
right 2 7
right 1 6
right 3 6
right 1 4
right 1 4
right 1 nan
right 1 nan
right 1 nan
Left 5 12
Left 4 8
Left 2 5
Left 1 4
Left 1 4
Left 1 nan
Left 1 nan
Left 1 nan

【问题讨论】:

    标签: python pandas rolling-computation


    【解决方案1】:

    我们可以使用偏移量为 -3 的FixedForwardWindowIndexer 作为window,而不是事后移动,而droplevel 可以删除移动中的附加索引,但保持DataFrame 的索引对齐:

    indexer = pd.api.indexers.FixedForwardWindowIndexer(window_size=4, offset=-3)
    df['rolling value'] = (
        df.groupby('movement')['value'].rolling(window=indexer).sum().droplevel(0)
    )
    

    df:

       movement  value  rolling value
    0     right      2            7.0
    1     right      1            6.0
    2     right      3            6.0
    3     right      1            4.0
    4     right      1            4.0
    5     right      1            NaN
    6     right      1            NaN
    7     right      1            NaN
    8      Left      5           12.0
    9      Left      4            8.0
    10     Left      2            5.0
    11     Left      1            4.0
    12     Left      1            4.0
    13     Left      1            NaN
    14     Left      1            NaN
    15     Left      1            NaN
    

    只是制作的系列:

    indexer = pd.api.indexers.FixedForwardWindowIndexer(window_size=4, offset=-3)
    print(df.groupby('movement')['value'].rolling(window=indexer).sum())
    
    movement    
    Left      8     12.0
              9      8.0
              10     5.0
              11     4.0
              12     4.0
              13     NaN
              14     NaN
              15     NaN
    right     0      7.0
              1      6.0
              2      6.0
              3      4.0
              4      4.0
              5      NaN
              6      NaN
              7      NaN
    Name: value, dtype: float64
    

    第一级 (movement) 是将值分配回 DataFrame 的问题(以及 groupby 不起作用的原因)。

    droplevel(0) 制作系列:

    8     12.0
    9      8.0
    10     5.0
    11     4.0
    12     4.0
    13     NaN
    14     NaN
    15     NaN
    0      7.0
    1      6.0
    2      6.0
    3      4.0
    4      4.0
    5      NaN
    6      NaN
    7      NaN
    Name: value, dtype: float64
    

    这将与 DataFrame 正确对齐。


    用于显示总和的 DataFrame 略有不同:

    import pandas as pd
    
    df = pd.DataFrame({
        'movement': ['right', 'right', 'right', 'right', 'right', 'right', 'right',
                     'right', 'Left', 'Left', 'Left', 'Left', 'Left', 'Left',
                     'Left', 'Left'],
        'value': [2, 1, 3, 1, 1, 1, 1, 1, 5, 4, 2, 1, 1, 1, 1, 1]
    })
    

    【讨论】:

    • 啊,这就是为什么你可以在没有sort=False 的情况下只使用droplevel,很好的解释
    • 谢谢@tdy 是的,索引对齐是其中之一,它要么超级有用,要么碍事。
    • 我想我更喜欢你的方法,Indexerdroplevel
    • 我想我需要更新熊猫。我收到错误:AttributeError:模块'pandas.api.indexers'没有属性'FixedForwardWindowIndexer'
    • @joshuah9 道歉。那是我的错误BaseIndex1.0.0 中引入。 FixedForwardWindowIndexer 直到 1.1.0 What’s new in 1.1.0 (July 28, 2020) Other enhancements 才被添加
    【解决方案2】:

    我尝试了 groupby,但它抛出了一个错误

    当您将分组结果作为一列重新分配时,索引将不会对齐,因此:

    1. 仅分配.values.array

      df['rolling'] = (df.groupby('movement', sort=False).value
                         .rolling(4).sum().shift(-3).array)
      
    2. 或者重置索引:

      df['rolling'] = (df.groupby('movement', sort=False).value
                         .rolling(4).sum().shift(-3).reset_index(drop=True))
      

    任一方法的输出:

       movement  value  rolling
    0     right      2      7.0
    1     right      1      6.0
    2     right      3      6.0
    3     right      1      4.0
    4     right      1      4.0
    5     right      1      NaN
    6     right      1      NaN
    7     right      1      NaN
    8      Left      5     12.0
    9      Left      4      8.0
    10     Left      2      5.0
    11     Left      1      4.0
    12     Left      1      4.0
    13     Left      1      NaN
    14     Left      1      NaN
    15     Left      1      NaN
    

    【讨论】:

      猜你喜欢
      • 2020-02-23
      • 1970-01-01
      • 2022-12-18
      • 2014-09-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-02-03
      • 2018-10-29
      相关资源
      最近更新 更多