【问题标题】:Pandas count over groups熊猫计数组
【发布时间】:2017-12-20 12:54:45
【问题描述】:

我有一个如下所示的 pandas 数据框:

ID  round   player1     player2 
1   1       A           B           
1   2       A           C
1   3       B           D
2   1       B           C           
2   2       C           D
2   3       C           E
3   1       B           C           
3   2       C           D
3   3       C           A

数据框包含运动比赛结果,其中ID 列表示一场比赛,round 列表示每场比赛的轮次,player1player2 列包含相互交手的球员的姓名在各自的round.

我现在想累计计算参加比赛的人数,例如玩家A。在伪代码中,这意味着:如果名称为A 的玩家出现在player1player2 每一场锦标赛ID 的列中,则计数器加1。

结果应该如下所示(注意:在我的示例中,玩家A 确实使用IDs 1 和3 参加了锦标赛):

ID  round   player1     player2     playerAparticipated
1   1       A           B           1
1   2       A           C           1
1   3       B           D           1
2   1       B           C           0
2   2       C           D           0
2   3       C           E           0
3   1       B           C           2
3   2       C           D           2
3   3       C           A           2

我目前的状态是,我添加了一个“帮助”列,其中包含值 10 表示,如果相应的玩家参加了比赛:

ID  round   player1     player2     helper
1   1       A           B           1
1   2       A           C           1
1   3       B           D           1
2   1       B           C           0
2   2       C           D           0
2   3       C           E           0
3   1       B           C           1
3   2       C           D           1
3   3       C           A           1

我认为我只需要最后一步,例如,巧妙地使用cumsum(),以所需的方式计算helper 列。但是,我还没有想出解决方案。

【问题讨论】:

  • 您需要数据框中的值吗? len(df[(df.player1 == 'A') | (df.player2 == 'A')].groupby('ID').count()) 会给你玩家“A”参加的锦标赛的数量。
  • 是的,我希望在原始数据框中包含这些值。

标签: python pandas count group-by cumsum


【解决方案1】:

我认为你需要:


df1 = df.drop_duplicates('ID').set_index('ID')
s = df1.loc[df1['helper'] != 0, 'helper'].cumsum().reindex(index=df1.index, fill_value=0)
df['playerAparticipated'] = df['ID'].map(s)
print (df)
   ID  round player1 player2  helper  playerAparticipated
0   1      1       A       B       1                    1
1   1      2       A       C       1                    1
2   1      3       B       D       1                    1
3   2      1       B       C       0                    0
4   2      2       C       D       0                    0
5   2      3       C       E       0                    0
6   3      1       B       C       1                    2
7   3      2       C       D       1                    2
8   3      3       C       A       1                    2

可以将joinrename 一起使用,而不是map

df = df.join(s.rename('playerAparticipated'), on='ID')
print (df)
   ID  round player1 player2  helper  playerAparticipated
0   1      1       A       B       1                    1
1   1      2       A       C       1                    1
2   1      3       B       D       1                    1
3   2      1       B       C       0                    0
4   2      2       C       D       0                    0
5   2      3       C       E       0                    0
6   3      1       B       C       1                    2
7   3      2       C       D       1                    2
8   3      3       C       A       1                    2

【讨论】:

  • 真的很喜欢这种使用reindex & map
  • 一个与您的答案相关的问题:为什么需要set_index?目的是什么?
  • 在我的解决方案中,它通过创建index 让列保持不变 - 因为需要处理helper
【解决方案2】:

与@jezrael 类似的方法,我做的慢了一点:)。

首先,将ID 移动到您的索引中:

df = df.reset_index().set_index(['index','ID'])
#          round player1 player2  helper
# index ID
# 0     1       1       A       B       1
# 1     1       2       A       C       1
# 2     1       3       B       D       1
# 3     2       1       B       C       0
# 4     2       2       C       D       0
# 5     2       3       C       E       0
# 6     3       1       B       C       1
# 7     3       2       C       D       1
# 8     3       3       C       A       1

接下来,过滤掉helper为0的行,得到ID的锦标赛累积总和,并将结果赋给一个变量:

tournament_count = df[df['helper'] > 0].groupby(['ID','helper']).first().reset_index(level=1)['helper'].cumsum().rename("playerAparticipated")
# ID
# 1    1
# 3    2

最后,用df加入tournament_count DataFrame:

df.join(tournament_counts, how="left").fillna(0)
#          round player1 player2  helper  tournament_counts
# index ID
# 0     1       1       A       B       1                1.0
# 1     1       2       A       C       1                1.0
# 2     1       3       B       D       1                1.0
# 3     2       1       B       C       0                0.0
# 4     2       2       C       D       0                0.0
# 5     2       3       C       E       0                0.0
# 6     3       1       B       C       1                2.0
# 7     3       2       C       D       1                2.0
# 8     3       3       C       A       1                2.0

【讨论】:

    猜你喜欢
    • 2018-04-29
    • 2017-03-21
    • 1970-01-01
    • 2020-12-19
    • 2021-11-11
    • 2022-01-12
    • 1970-01-01
    相关资源
    最近更新 更多