我有一个包含以下各列的数据框:
| winner | loser | tournament |
+--------+---------+------------+
| John | Steve | A |
+--------+---------+------------+
| Steve | John | B |
+--------+---------+------------+
| John | Michael | A |
+--------+---------+------------+
| Steve | John | A |
+--------+---------+------------+
我想要做的是针对给定的锦标赛类型计算获胜者和失败者的历史获胜百分比,并将其放在自己的栏中。
填写上表的示例如下。游戏将被称为(赢家,输家,类型)。
我还添加了中间计算列,以使其更清晰。
1)对于第一场比赛(John,Steve,A)。以前没有A型游戏。因此我们填充0。
2)第二局(Steve,John,B)。以前没有类型B的游戏。因此我们填充0。
3)第三局(John,Michael,A)。以前有A型游戏,所以我们可以获得信息。首先,约翰是赢家。他在表的第一行赢得了A类的一场比赛。因此,我们将获胜者获胜=1。John之前没有输过A类游戏,因此我们将获胜者损失=0。Michael没有任何比赛历史,因此我们将失败者获胜= 0,并将失败者损失= 0。
4)对于第四局,(史蒂夫·约翰,A)。我们看到史蒂夫以前从未赢得过任何A类游戏,因此我们将获胜者获胜次数设为0。他输了1场A类游戏(第一行)。因此,我们将获胜者损失=1。约翰赢得了2场A类比赛,因此失败者获胜=2。他已经输了
+--------+---------+------------+-------------+------------+---------------+--------------+--------------+-------------+
| winner | loser | tournament | winner wins | loser wins | winner losses | loser losses | winner win % | loser win % |
+--------+---------+------------+-------------+------------+---------------+--------------+--------------+-------------+
| John | Steve | A | 0 | 0 | 0 | 0 | 0/(0+0) | 0/(0+0) |
+--------+---------+------------+-------------+------------+---------------+--------------+--------------+-------------+
| Steve | John | B | 0 | 0 | 0 | 0 | 0/(0+0) | 0/(0+0) |
+--------+---------+------------+-------------+------------+---------------+--------------+--------------+-------------+
| John | Michael | A | 1 | 0 | 0 | 0 | 1/(1+0) | 0/(0+0) |
+--------+---------+------------+-------------+------------+---------------+--------------+--------------+-------------+
| Steve | John | A | 0 | 2 | 1 | 0 | 0/(0+1) | 2/(2+0) |
+--------+---------+------------+-------------+------------+---------------+--------------+--------------+-------------
这应该产生预期的结果:
def win_los_percent(sdf):
sdf['winner wins'] = sdf.groupby('winner').cumcount()
sdf['winner losses'] = [(sdf.loc[0:i, 'loser'] == sdf.loc[i, 'winner']).sum() for i in sdf.index]
sdf['loser losses'] = sdf.groupby('loser').cumcount()
sdf['loser wins'] = [(sdf.loc[0:i, 'winner'] == sdf.loc[i, 'loser']).sum() for i in sdf.index]
sdf['winner win %'] = sdf['winner wins'] / (sdf['winner wins'] + sdf['winner losses'])
sdf['loser win %'] = sdf['loser wins'] / (sdf['loser wins'] + sdf['loser losses'])
return sdf
ddf = df.groupby('tournament').apply(win_los_percent)
使用提供的数据ddf
是:
winner loser tournament winner wins winner losses loser losses loser wins winner win % loser win %
0 John Steve A 0 0 0 0 NaN NaN
1 Steve John B 0 0 0 0 NaN NaN
2 John Michael A 1 0 0 0 1.0 NaN
3 Steve John A 0 1 0 2 0.0 1.0
pandas groupby用于对同一锦标赛的数据进行分组,并将子数据帧传递给该win_los_percent
函数。返回此函数的返回值以构建最终数据帧。
对于每个子集,该函数计算几列:
sdf['winner wins']
并sdf['loser losses']
通过使用cumcount获得:对于每一行,此方法都会对分组列中先前出现的值(玩家名称)进行计数。sdf['winner losses']
和sdf['loser wins']
详细说明,因为我们需要计算另一列中先前出现的值(玩家名称)。'winner'
是否等于列中当前行的播放器名称,loser
反之亦然。sum()
允许计算True值:True强制转换为1,False强制转换为0,总和给出所需的结果:前几行中出现了多少名玩家名称。NaN
是因为被0除。本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句