在pandas数据框架中按组累计计数范围之间的值



假设我有以下数据。对于每个user_id,我想在每次差值为<= -2时获得累积计数,直到它达到正值。然后,计数应该重置为0,并保持在该值,直到遇到该用户的下一个<= -2,此时计数再次从1开始,直到达到下一个正值。结果应该等于我在cum_count中的结果。

df = pd.DataFrame({'user_id': [1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3],
'difference_score': [0.0, 1.0, -2.5, -2.5, -0.5, -1.5, 2.25, 2.25, -1.86, 0.0, -0.33, -1.33, -2.33, 0.0, 1.0, -2.67, -0.67, -0.67, 0.67, -0.33, -0.33, 1.0],
'cum_count': [0, 0, 1, 2, 3, 4, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 2, 3, 0, 0, 0, 0]})
user_id  difference_score  cum_count
0         1            0.0000          0
1         1            1.0000          0
2         1           -2.5000          1
3         1           -2.5000          2
4         1           -0.5000          3
5         1           -1.5000          4
6         1            2.2500          0
7         1            2.2500          0
8         2           -1.8571          0
9         2            0.0000          0
10        2           -0.3333          0
11        2           -1.3333          0
12        2           -2.3333          1
13        2            0.0000          0
14        3            1.0000          0
15        3           -2.6667          1
16        3           -0.6667          2
17        3           -0.6667          3
18        3            0.6667          0
19        3           -0.3333          0
20        3           -0.3333          0
21        3            1.0000          0

编辑:基于你的解决方案mozway,我发现了几个实例,其中提出的解决方案没有产生预期的结果。抱歉,我的示例数据不够广泛。我现在扩展了上面的示例数据,以突出显示这一点。

例如,在下面的更新数据框中,第14行cum_count应该为0,因为它是一个新用户,并且差值为>2。但是,cum_count2产生一个1。

此外,一旦达到正值,计数重置为0,下一次遇到该用户的值<= -2时,计数应从1重新开始。但是,在第19行中,cum_count2继续从前一个计数开始计数。

更新后的cum_count列有我期望返回的值,与当前解决方案在cum_count2中返回的值相比…

df = pd.DataFrame({'user_id': [1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3],
'difference_score': [0.0, 1.0, -2.5, -2.5, -0.5, -1.5, 2.25, 2.25, -1.86, 0.0, -0.33, -1.33, -2.33, -2.0, -1.0, -2.67, -0.67, -0.67, 0.67, -2.5, -0.33, 1.0],
'cum_count': [0, 0, 1, 2, 3, 4, 0, 0, 0, 0, 0, 0, 1, 2, 0, 1, 2, 3, 0, 1, 2, 0]})
user_id  difference_score  cum_count  cum_count2
0         1              0.00          0           0
1         1              1.00          0           0
2         1             -2.50          1           1
3         1             -2.50          2           2
4         1             -0.50          3           3
5         1             -1.50          4           4
6         1              2.25          0           0
7         1              2.25          0           0
8         2             -1.86          0           0
9         2              0.00          0           0
10        2             -0.33          0           0
11        2             -1.33          0           0
12        2             -2.33          1           1
13        2             -2.00          2           2
14        3             -1.00          0           1
15        3             -2.67          1           2
16        3             -0.67          2           3
17        3             -0.67          3           4
18        3              0.67          0           0
19        3             -2.50          1           5
20        3             -0.33          2           6
21        3              1.00          0           0

您可以使用掩码来定义开始和停止,识别连续匹配的值,并使用它来生成一个组来执行计数:

m1 = df['difference_score'].ge(0)
m2 = df['difference_score'].le(-2)
m3 = m2.groupby([df['user_id'], m1.cumsum()]).cummax()
group = (m3&~m3.groupby(df['user_id']).shift(fill_value=False)).cumsum()
df['cum_count'] = df.groupby(['user_id', group]).cumcount().add(1).where(m3, 0)

输出:

user_id  difference_score  cum_count     m1     m2     m3  group
0         1              0.00          0   True  False  False      0
1         1              1.00          0   True  False  False      0
2         1             -2.50          1  False   True   True      1
3         1             -2.50          2  False   True   True      1
4         1             -0.50          3  False  False   True      1
5         1             -1.50          4  False  False   True      1
6         1              2.25          0   True  False  False      1
7         1              2.25          0   True  False  False      1
8         2             -1.86          0  False  False  False      1
9         2              0.00          0   True  False  False      1
10        2             -0.33          0  False  False  False      1
11        2             -1.33          0  False  False  False      1
12        2             -2.33          1  False   True   True      2
13        2             -2.00          2  False   True   True      2
14        3             -1.00          0  False  False  False      2
15        3             -2.67          1  False   True   True      3
16        3             -0.67          2  False  False   True      3
17        3             -0.67          3  False  False   True      3
18        3              0.67          0   True  False  False      3
19        3             -2.50          1  False   True   True      4
20        3             -0.33          2  False  False   True      4
21        3              1.00          0   True  False  False      4

相关内容

  • 没有找到相关文章

最新更新