我有一个有许多列的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
为1
的SD
,x2
为1,2
的SD;x5
是1,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 from
的SD
3到21 ' ' ',以此类推。我想对多个列做这样的操作,并生成多个SD
我不知道如何使用expanding
函数对于这种移动窗口。同样的方法计算平均值,是不是只用mean
函数代替std()
?
您只需要确定每行的下界和上界,然后就很容易了:
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()
:
lower
和upper
列df >> select(~c(f.lower, f.upper))
免责声明:我是datar
的作者,它是pandas
的包装,在R
中实现dplyr
/tidyr
的一些功能。