Reputation: 14604
I would like to calculate the standard deviation of a value, by group. I am getting unexpected results. Can someone help?
from numpy import nan
df = {'value': {1: nan, 2: nan, 3: nan, 4: nan, 5: nan, 6: nan, 7: nan, 8: nan, 9: nan, 10: 0.1, 11: 0.3, 12: 0.6, 13: 0.2, 14: -0.1, 15: 0.2}}
df = pd.DataFrame.from_dict(df)
df['group'] = [1,2,1,2,1,2,1,2,1,2,1,2,1,2,1]
df['rolling_std'] = df.groupby('group')['value'].rolling(3).std().values
df.head(15)
value group rolling_std
1 NaN 1 NaN
2 NaN 2 NaN
3 NaN 1 NaN
4 NaN 2 NaN
5 NaN 1 NaN
6 NaN 2 NaN
7 NaN 1 NaN
8 NaN 2 0.057735 # here I expect NaN since all values from group 2 are NaN so far
9 NaN 1 NaN
10 0.1 2 NaN
11 0.3 1 NaN
12 0.6 2 NaN
13 0.2 1 NaN
14 -0.1 2 NaN
15 0.2 1 0.360555
Upvotes: 3
Views: 3974
Reputation: 862406
I believe you need GroupBy.apply
:
df['rolling_std'] = df.groupby('group')['value'].apply(lambda x : x.rolling(3).std())
Or remove first level of MultiIndex for align by index values, because if use .values
it assign numpy array with different order:
df['rolling_std'] = (df.groupby('group')['value']
.rolling(3)
.std()
.reset_index(level=0, drop=True))
print (df)
value group rolling_std
1 NaN 1 NaN
2 NaN 2 NaN
3 NaN 1 NaN
4 NaN 2 NaN
5 NaN 1 NaN
6 NaN 2 NaN
7 NaN 1 NaN
8 NaN 2 NaN
9 NaN 1 NaN
10 0.1 2 NaN
11 0.3 1 NaN
12 0.6 2 NaN
13 0.2 1 NaN
14 -0.1 2 0.360555
15 0.2 1 0.057735
Detail:
print (df.groupby('group')['value']
.rolling(3)
.std())
group
1 1 NaN
3 NaN
5 NaN
7 NaN
9 NaN
11 NaN
13 NaN
15 0.057735
2 2 NaN
4 NaN
6 NaN
8 NaN
10 NaN
12 NaN
14 0.360555
Name: value, dtype: float64
print (df.groupby('group')['value']
.rolling(3)
.std()
.values)
[ nan nan nan nan nan nan
nan 0.05773503 nan nan nan nan
nan nan 0.36055513]
Upvotes: 3