基于掩码条件的熊猫滚动计算?

时间:2021-03-05 13:13:32

标签: python pandas

我有以下格式的数据框:

>>> 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 循环类型的查找,但这不适合我对这个用例的需求。

3 个答案:

答案 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 单元格值,其中 dfmask 但如果 False 为 {{ 1}}。