首页 > 解决方案 > Pandas:按组条件滚动计数,计算当前观察出现在另一列的次数

问题描述

我正在尝试对在另一列中指定的组给定固定窗口长度的情况下出现在一个列中的观察结果进行滚动计数。用一个例子可以更好地解释这一点:

df = pd.DataFrame({'B': ['X', 'X' , 'Y', 'X', 'Y', 'Y', 'X', 'X', 'Y', 'Y', 'X', 'Y'],
                   'group': ["IT", "IT", "IT", "MV", "MV", "MV", "IT", "MV", "MV", "IT", "IT", "MV"]})

我想对'group'进行分组并对B列中的'X'和'Y'进行滚动计数,窗口长度= 3。如果'X'是当前行,那么我们要计算'X'的次数出现在组“组”中的前 3 个观察值中,不包括当前行的计数(因此向后移动 period=1)。对于这个例子,我还需要 min_periods=1。

输出应该看起来像

     B group  count
0    X    IT    0
1    X    IT    1
2    Y    IT    0
3    X    MV    0
4    Y    MV    0
5    Y    MV    1
6    X    IT    2
7    X    MV    1
8    Y    MV    2
9    Y    IT    1
10   X    IT    1
11   Y    MV    2

我已经尝试了以下代码,但它并不完全正确。这按“组”和“B”计算。计数应该按“组”计算,“B”中的观察值应该按“组”内的最后 3 个周期计算。

df['count'] = df.groupby(['group', 'B']).transform(lambda x: x.rolling(3, min_periods=1).count().shift(fill_value=0))

标签: pythonpandas

解决方案


我在下面有一个解决方案,但我正在寻找一个更好的解决方案,因为“B”列可能有许多不同的观察结果,使其非常缓慢。

for i in df['B'].unique():
    df.loc[df['B']==i, 'count'] = df.where(df['B'].eq(i)).groupby(df['group'])['B'].transform(lambda x: x.rolling(3, min_periods=1).count().shift(fill_value=0))
df

    B group count
0   X   IT  0.0
1   X   IT  1.0
2   Y   IT  0.0
3   X   MV  0.0
4   Y   MV  0.0
5   Y   MV  1.0
6   X   IT  2.0
7   X   MV  1.0
8   Y   MV  2.0
9   Y   IT  1.0
10  X   IT  1.0
11  Y   MV  2.0

推荐阅读