形成子组并根据值增加/减少

发布于 2025-01-10 21:48:52 字数 3169 浏览 0 评论 0原文

我的初始数据框如下所示(除了列 Counter):

IndexUserStatusCounter
1JohnA1
2EllenA1
3JohnB0
4EllenA2
5JohnA1
6JohnA2
7JohnA3
8约翰A4
9艾伦A3
10约翰B3
11艾伦B2
12艾伦C1
13艾伦A2
14EllenA3

在本例中,我有两个用户 (John/Ellen)。事实上,用户还有更多。

Counter 列是我要实现的目标。如果我只有一个用户,代码将如下所示:

count = 0
CounterList = []
for i, row in df.iterrows():
  if row["Status"] == "A":
    count += 1
  elif row["Status"] == "B" or row["Status"] == "C":
    count -= 1
  CounterList.append(count)
df["Counter"] = CounterList
df

对于状态 A,计数器加 1,对于状态 B 或 C,计数器减 1。

但如何处理两个或更多用户呢?如何建立子组并分别统计每个用户子组?

My intial Dataframe looks as follows (except column Counter):

IndexUserStatusCounter
1JohnA1
2EllenA1
3JohnB0
4EllenA2
5JohnA1
6JohnA2
7JohnA3
8JohnA4
9EllenA3
10JohnB3
11EllenB2
12EllenC1
13EllenA2
14EllenA3

In this case I have two users (John/Ellen). In fact, there are way more users.

The Counter column is my goal to achieve. If I had only one user, the code would look like this:

count = 0
CounterList = []
for i, row in df.iterrows():
  if row["Status"] == "A":
    count += 1
  elif row["Status"] == "B" or row["Status"] == "C":
    count -= 1
  CounterList.append(count)
df["Counter"] = CounterList
df

With status A it counts up by 1, with status B or C the counter is reduced by one.

But how to handle two or more users? How to build subgroups and counting each user-subgroup separately?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

青衫负雪 2025-01-17 21:48:52

创建 Status 到对应分数的映射;然后groupby + cumsum

mapping = {'A':1, 'B':-1,'C':-1}        
df['Counter'] = df.assign(Counter=df['Status'].map(mapping)).groupby('User')['Counter'].cumsum()

输出:

    Index   User Status  Counter
0       1   John      A        1
1       2  Ellen      A        1
2       3   John      B        0
3       4  Ellen      A        2
4       5   John      A        1
5       6   John      A        2
6       7   John      A        3
7       8   John      A        4
8       9  Ellen      A        3
9      10   John      B        3
10     11  Ellen      B        2
11     12  Ellen      C        1
12     13  Ellen      A        2
13     14  Ellen      A        3

Create a mapping from Status to its corresponding score; then groupby + cumsum:

mapping = {'A':1, 'B':-1,'C':-1}        
df['Counter'] = df.assign(Counter=df['Status'].map(mapping)).groupby('User')['Counter'].cumsum()

Output:

    Index   User Status  Counter
0       1   John      A        1
1       2  Ellen      A        1
2       3   John      B        0
3       4  Ellen      A        2
4       5   John      A        1
5       6   John      A        2
6       7   John      A        3
7       8   John      A        4
8       9  Ellen      A        3
9      10   John      B        3
10     11  Ellen      B        2
11     12  Ellen      C        1
12     13  Ellen      A        2
13     14  Ellen      A        3
海风掠过北极光 2025-01-17 21:48:52

您可以检查 Status 是否等于 A 并映射 1,否则为 -1。然后对每组执行 cumsum:

df['Counter'] = (df['Status']
                 .eq('A').map({True: 1, False: -1}) # make A: 1, other: -1
                 .groupby(df['User']).cumsum()      # cumsum per group
                 )

输出:

    Index   User Status  Counter
0       1   John      A        1
1       2  Ellen      A        1
2       3   John      B        0
3       4  Ellen      A        2
4       5   John      A        1
5       6   John      A        2
6       7   John      A        3
7       8   John      A        4
8       9  Ellen      A        3
9      10   John      B        3
10     11  Ellen      B        2
11     12  Ellen      C        1
12     13  Ellen      A        2
13     14  Ellen      A        3

You can check if the Status is equal to A and map 1, -1 otherwise. Then perform a cumsum per group:

df['Counter'] = (df['Status']
                 .eq('A').map({True: 1, False: -1}) # make A: 1, other: -1
                 .groupby(df['User']).cumsum()      # cumsum per group
                 )

output:

    Index   User Status  Counter
0       1   John      A        1
1       2  Ellen      A        1
2       3   John      B        0
3       4  Ellen      A        2
4       5   John      A        1
5       6   John      A        2
6       7   John      A        3
7       8   John      A        4
8       9  Ellen      A        3
9      10   John      B        3
10     11  Ellen      B        2
11     12  Ellen      C        1
12     13  Ellen      A        2
13     14  Ellen      A        3
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文