【问题标题】:Dataframe rolling mean, replaces column, how do I keep the original column and add the rolling mean as a new column?数据框滚动平均值,替换列,如何保留原始列并将滚动平均值添加为新列?
【发布时间】:2020-10-12 10:08:54
【问题描述】:

我有一个 DF:

  tbname    stat_day    count
0    calc_10  2020-05-01        0
1    calc_10  2020-05-02        0
2    calc_10  2020-05-03        0
<snip>
49   calc_10  2020-06-19      361
50   calc_10  2020-06-20      506
51   calc_10  2020-06-21        0
52   calc_10  2020-06-22        0
53   calc_12  2020-05-01        0
54   calc_12  2020-05-02        0
<snip>
73   calc_12  2020-05-21        0
74   calc_12  2020-05-22        0
75   calc_12  2020-05-23        0
<snip>

然后我将它分组并得到一个滚动平均值:

gp=df_tsd.groupby(['tbname'])
df_gp=gp.rolling(30,on='stat_day').mean()

我想保留计数列并添加一个 RMA 列,但是 rolling().mean() 将计数列替换为滚动值:

               stat_day          count
tbname                                
calc_10 0    2020-05-01            NaN
        1    2020-05-02            NaN
        2    2020-05-03            NaN
<snip>        41   2020-06-11       0.000000
        42   2020-06-12     249.533333
        43   2020-06-13     777.333333
        44   2020-06-14    1310.333333
        45   2020-06-15    1841.700000
        46   2020-06-16    2235.933333
        47   2020-06-17    2259.933333
        48   2020-06-18    2283.200000
        49   2020-06-19    2295.233333
        50   2020-06-20    2312.100000
        51   2020-06-21    2312.100000
        52   2020-06-22    2312.100000

更新: 您的代码有效! (自然),我添加了一些调整:

df_tsd['RDA']=df_tsd.groupby('tbname')['count'].transform(lambda x: x.rolling(7).mean())
print(df_tsd.groupby('tbname').tail(30).round({'RDA':0}).to_string(index=False))

这是输出:

  tbname    stat_day  count     RDA
 calc_10  2020-05-24      0     0.0
 calc_10  2020-05-25      0     0.0
 calc_10  2020-05-26      0     0.0
 calc_10  2020-05-27      0     0.0
 calc_10  2020-05-28      0     0.0
 calc_10  2020-05-29      0     0.0
 calc_10  2020-05-30      0     0.0
<snip>
 calc_10  2020-06-12   7486  1069.0
 calc_10  2020-06-13  15834  3331.0
 calc_10  2020-06-14  15990  5616.0
 calc_10  2020-06-15  15941  7893.0
 calc_10  2020-06-16  11827  9583.0
 calc_10  2020-06-17    720  9685.0
 <snip>
calc_12  2020-06-02   1959   280.0
 calc_12  2020-06-03   1582   506.0
 calc_12  2020-06-04      0   506.0

我的代码(不太好用)最终没有新的滚动列,但输出很整洁,请注意 tbname 上的控制中断:

              stat_day   count
tbname                        
calc_10 23  2020-05-24     0.0
        24  2020-05-25     0.0
        25  2020-05-26     0.0
        26  2020-05-27     0.0
<snip>
calc_12 70  2020-05-18     0.0
        71  2020-05-19     0.0
        72  2020-05-20     0.0
<snip>
        88  2020-06-05   506.0
        89  2020-06-06   506.0

【问题讨论】:

    标签: pandas dataframe mean rolling-computation


    【解决方案1】:

    您不必分两步完成。您可以使用transform 函数在一行中执行此操作,只需将移动平均列添加到您的基本数据框。

    我稍微更改了您的数据以作为示例。有关我认为您正在寻找的基本数据、命令和输出,请参见下文。我使用了 3 天移动平均线,以便于显示。

    然后,如果您想将其与分组一起显示,请执行您最初的操作,但要使用 1 天的移动窗口。

    >>> df
         tbname     statday  count
    0   calc_10  2020-05-01      1
    1   calc_10  2020-05-02      2
    2   calc_10  2020-05-03      3
    3   calc_10  2020-05-04      4
    4   calc_10  2020-05-05      5
    5   calc_10  2020-05-06      6
    6   calc_10  2020-05-07      7
    7   calc_10  2020-05-08      8
    8   Calc_11  2020-05-01      1
    9   Calc_11  2020-05-02      2
    10  Calc_11  2020-05-03      3
    11  Calc_11  2020-05-04      4
    12  Calc_11  2020-05-05      5
    13  Calc_11  2020-05-06      6
    14  Calc_11  2020-05-07      7
    15  Calc_12  2020-05-01      1
    16  Calc_12  2020-05-02      2
    17  Calc_12  2020-05-03      3
    18  Calc_12  2020-05-04      4
    19  Calc_12  2020-05-05      5
    20  Calc_12  2020-05-06      6
    21  Calc_12  2020-05-07      7
    22  Calc_12  2020-05-08      8
    23  Calc_12  2020-05-09      9
    >>> df['ma'] = df.groupby('tbname')['count'].transform(lambda x: x.rolling(3).mean())
    >>> df
         tbname     statday  count   ma
    0   calc_10  2020-05-01      1  NaN
    1   calc_10  2020-05-02      2  NaN
    2   calc_10  2020-05-03      3  2.0
    3   calc_10  2020-05-04      4  3.0
    4   calc_10  2020-05-05      5  4.0
    5   calc_10  2020-05-06      6  5.0
    6   calc_10  2020-05-07      7  6.0
    7   calc_10  2020-05-08      8  7.0
    8   Calc_11  2020-05-01      1  NaN
    9   Calc_11  2020-05-02      2  NaN
    10  Calc_11  2020-05-03      3  2.0
    11  Calc_11  2020-05-04      4  3.0
    12  Calc_11  2020-05-05      5  4.0
    13  Calc_11  2020-05-06      6  5.0
    14  Calc_11  2020-05-07      7  6.0
    15  Calc_12  2020-05-01      1  NaN
    16  Calc_12  2020-05-02      2  NaN
    17  Calc_12  2020-05-03      3  2.0
    18  Calc_12  2020-05-04      4  3.0
    19  Calc_12  2020-05-05      5  4.0
    20  Calc_12  2020-05-06      6  5.0
    21  Calc_12  2020-05-07      7  6.0
    22  Calc_12  2020-05-08      8  7.0
    23  Calc_12  2020-05-09      9  8.0
    >>> dfgp=df.groupby(['tbname'])
    >>> df_gp=gp.rolling(1,on='statday').mean()
    >>> df_gp
                   statday  count   ma
    tbname                            
    Calc_11 8   2020-05-01    1.0  NaN
            9   2020-05-02    2.0  NaN
            10  2020-05-03    3.0  2.0
            11  2020-05-04    4.0  3.0
            12  2020-05-05    5.0  4.0
            13  2020-05-06    6.0  5.0
            14  2020-05-07    7.0  6.0
    Calc_12 15  2020-05-01    1.0  NaN
            16  2020-05-02    2.0  NaN
            17  2020-05-03    3.0  2.0
            18  2020-05-04    4.0  3.0
            19  2020-05-05    5.0  4.0
            20  2020-05-06    6.0  5.0
            21  2020-05-07    7.0  6.0
            22  2020-05-08    8.0  7.0
            23  2020-05-09    9.0  8.0
    calc_10 0   2020-05-01    1.0  NaN
            1   2020-05-02    2.0  NaN
            2   2020-05-03    3.0  2.0
            3   2020-05-04    4.0  3.0
            4   2020-05-05    5.0  4.0
            5   2020-05-06    6.0  5.0
            6   2020-05-07    7.0  6.0
            7   2020-05-08    8.0  7.0
    

    【讨论】:

    • 哦,我的,transform 和 lambda!让我试一试。谢谢!
    • 我在上面添加和更新,感谢您的帮助,但我确实喜欢我的示例如何通过 tbname 打破输出。作为 Pandas 的新手,我无法解释,...有什么想法吗?
    • 哦,我明白了,你想要 tbname 中的单行输出。只需在我的示例中使用 df ,然后执行您所做的操作:groupby 然后滚动,使用 1 天窗口。我会把它添加到我的答案中
    • 非常感谢,感谢您的帮助。我还有很多东西要学,哈哈!
    • @PhilippeGodfrin 没问题。如果您发现一个有用的答案,通常最好使用答案左侧的箭头对其进行投票:)
    猜你喜欢
    • 2021-08-07
    • 1970-01-01
    • 2017-03-09
    • 2020-09-20
    • 1970-01-01
    • 1970-01-01
    • 2019-04-16
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多