【问题标题】:Moving window on a Standard Deviation & Mean calculation标准偏差和平均值计算的移动窗口
【发布时间】:2021-11-04 14:43:45
【问题描述】:

我有一个df,它有很多列。我目前正在使用以下命令 output = df.join(df.expanding().std().fillna(0).add_prefix("SD")) 根据这样的累积值为 A 列生成标准偏差列:

A   SDA
1       x1
2       x2
3       x3
4       x4
5       x5

其中x1 1SDx21,2 的SD; x51,2,3,4,5 的 SD 等等。 我想移动窗口,使其移动到11 后,SD 将根据值2 to 11 计算。

A      SDA
1       x1
2       x2
3       x3
..      ..
9       x9
10      x10
11      x11
12      x12
13      x13
..      ..
20      x20
21      x21
22      x22

因此,这里 x11 将计算来自 2,3,4..11 和 **x12 ** 的值的标准偏差将是 2 to 12 。因此,x20 将是基于2 to 20。在20个值之后,它会再次移动一步,x21将是3,4,5,6...21`` .x22will be based on values from3的SD到21```等等。我想对多个列进行这样的操作,一次生成多个 SD 列。

我不知道如何为这种移动窗口使用expanding 函数。 为了以同样的方式计算平均值,我应该只使用mean 函数代替std() 吗?

【问题讨论】:

    标签: python pandas statistics data-analysis standard-deviation


    【解决方案1】:

    你只需要确定每一行的下限和上限,就很简单了:

    from datar.all import (
        f, across, c, tibble, mutate, row_number, std, rnorm
    )
    
    # Create a example df
    df = tibble(A=rnorm(22), B=rnorm(22))
    
    def stdev(col, lower, upper):
        """Calculate the stdev with the lower- and upper-bound of current column"""
        return [std(col[low:up]) for low, up in zip(lower, upper)]
    
    (
        df
        >> mutate(
            # create the lower- and upper-bound
            # note it's 0-based
            upper=row_number(),
            lower=(f.upper - 1) // 10,
        )
        >> mutate(
            across(
                # Apply stdev func to each column except the lower and upper columns
                ~c(f.lower, f.upper),
                stdev,
                lower=f.lower,
                upper=f.upper,
                _names="SD{_col}",
            )
        )
    )
    
               A         B   upper   lower       SDA       SDB
       <float64> <float64> <int64> <int64> <float64> <float64>
    0  -0.399324  0.740135       1       0       NaN       NaN
    1  -0.023364  0.468155       2       0  0.265844  0.192318
    2   0.839819 -0.899893       3       0  0.635335  0.878940
    3  -0.788705  0.497236       4       0  0.695902  0.744258
    4   1.838374 -0.153098       5       0  1.053171  0.663758
    5   0.174278 -0.938773       6       0  0.943238  0.736899
    6   0.265525  1.906103       7       0  0.861060  0.998927
    7   0.484971  1.687661       8       0  0.800723  1.058484
    8   0.238861  1.378369       9       0  0.749275  1.041054
    9   1.068637 -0.075925      10       0  0.747869  0.999481
    10 -1.742042 -0.192375      11       1  0.984440  1.013941
    11 -0.779599 -1.944827      12       1  0.982807  1.188045
    12 -0.478696  0.211798      13       1  0.954120  1.132865
    13 -2.598185 -0.747964      14       1  1.179397  1.113613
    14 -0.308082  0.171333      15       1  1.134297  1.070135
    15  0.700852 -2.719584      16       1  1.113848  1.261954
    16  0.917145  0.375815      17       1  1.104229  1.224715
    17  1.343796 -0.796525      18       1  1.118582  1.199169
    18  1.024335 -0.943663      19       1  1.108354  1.180068
    19 -0.877742 -0.431288      20       1  1.101227  1.148623
    20 -0.584439 -0.555945      21       2  1.111302  1.141233
    21 -0.946391 -1.550432      22       2  1.103871  1.149968
    

    您终于可以使用select() 删除lowerupper 列:

    df >> select(~c(f.lower, f.upper))
    

    免责声明:我是datar 的作者,它是pandas 的封装,用于在R 中实现dplyr/tidyr 中的一些功能。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-03-04
      • 2014-03-21
      • 1970-01-01
      • 2020-09-18
      • 1970-01-01
      • 2012-04-20
      相关资源
      最近更新 更多