熊猫数量超过群体

时间:2017-07-15 15:05:21

标签: python pandas count group-by cumsum

我有一个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的玩家出现在每个锦标赛player1的{​​{1}}或player2列中,请将计数器增加1。

结果应如下所示(注意:在我的示例中,播放器ID确实参加了A s 1和3的锦标赛:

ID

我目前的状态是,我添加了一个“帮助”列,其中包含值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 1,表示相应的玩家是否参与了锦标赛:

0

我认为我只需要最后一步,例如,聪明地使用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()列。但是,我还没有想出解决方案。

2 个答案:

答案 0 :(得分:4)

我认为你需要:

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

map可以rename使用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

let resultArr = idsNameIntvalueArr.filter({ idsArr.contains($0[0] as! String) }).map({ [$0[1], $0[2]] })

答案 1 :(得分:1)

对@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