我有以下格式的数据框:
>>> df = pd.DataFrame(np.random.randint(0,100,size=(100, 4)), columns=list('ABCD'))
A B C D
0 58 3 25 94
1 54 4 99 85
2 87 98 74 36
3 63 68 79 51
4 25 7 42 12
.. .. .. .. ..
95 50 19 90 99
96 68 1 52 98
97 96 2 98 21
98 90 25 5 23
99 56 93 48 19
我想重新计算满足特定标准的那些值。可以有很多标准,但为了简单起见,我们只采用一个简单的标准:如果单元格值低于数据帧平均值的 10%:
>>> mask = df<0.1*df.mean().mean()
A B C D
0 False True False False
1 False True False False
2 False False False False
3 False False False False
4 False False False False
.. ... ... ... ...
95 False False False False
96 False True False False
97 False True False False
98 False False True False
99 False False False False
对于满足此条件的每个单元格,我想创建一个大小为 10 的滚动窗口,计算该滚动窗口的均值,并用该均值替换单元格的值。对于原始 df
数据框中的所有其余单元格,应保留原始值。因此我们可以直观地认为:如果我们看到一个太低的值,让我们用最后 10 个(实际上只有 9 个,因为在 pandas 中定义滚动窗口的方式)值的平均值来替换它。>
现在我有点了解如何从这里前进。 df[mask]
将向我显示满足条件的单元格,但我无法对其应用 .rolling()
,因为 df[mask]
在所有其他不满足条件的单元格中有 NaN
条件。
请注意,我更喜欢高性能,因为实际上标准和滚动窗口计算都会更复杂,并且数据框要大得多。因此,我可以做一个简单的 for 循环类型的查找,但这不适合我对这个用例的需求。
答案 0 :(得分:1)
如果我正确理解问题:
mask = df < 0.1 * df.mean().mean()
df[mask] = df.rolling(10, 0).mean()[mask]
答案 1 :(得分:0)
取决于您想如何处理 NaN,但一种方法很简单:df[mask].fillna(0).rolling(10).mean()
答案 2 :(得分:0)
我设法解决了这个问题:我没有专注于弄清楚如何只为那些满足标准的单元格执行滚动窗口计算,而是首先计算了整个数据框:
>>> means = df.rolling(10).mean()
A B C D
0 NaN NaN NaN NaN
1 NaN NaN NaN NaN
2 NaN NaN NaN NaN
3 NaN NaN NaN NaN
4 NaN NaN NaN NaN
.. ... ... ... ...
95 46.3 35.2 44.8 41.5
96 46.1 40.0 42.0 48.0
97 49.6 45.6 42.8 52.6
98 46.7 39.5 40.3 49.9
99 43.6 42.5 35.9 46.7
然后,我简单地将 df[mask]
where mask = df<0.1*df.mean()*mean()
分配给它,如下所示:
means
这会保留原来的 df[mask] = means
单元格值,其中 df
为 mask
但如果 False
为 {{ 1}}。