非索引日期时间列的基于滚动时间的groupby()平均值

2024-05-29 05:01:00 发布

您现在位置:Python中文网/ 问答频道 /正文

我需要知道一个玩家是否在过去4.5小时内赢得了超过一半的前一场比赛(不包括当前比赛)。...rolling('4.5h')...的变体不起作用,因为时间列不是索引,不能与set_index('game_t')一起转换。你知道吗

游戏由gid(游戏ID)列表示,wl列中的“w”和“l”分别表示赢和输。每个游戏id的游戏时间都存储在game_t

我有一个数据帧,下面是一个很好的最小近似值:

df = pd.DataFrame({'game_t': [pd.datetime.now() - dt.timedelta(hours=n) for n in range(10)],
                    'player': [*'abacabaccb'],
                    'wl': ['w','l']*5,
                    'gid': [1,1,2,2,3,3,4,4,5,5]})
df.game_t = df.groupby('gid').game_t.transform('first')
df
#                       game_t player wl  gid
# 0 2019-07-05 15:00:23.840588      a  w    1
# 1 2019-07-05 15:00:23.840588      b  l    1
# 2 2019-07-05 13:00:23.840605      a  w    2
# 3 2019-07-05 13:00:23.840605      c  l    2
# 4 2019-07-05 11:00:23.840611      a  w    3
# 5 2019-07-05 11:00:23.840611      b  l    3
# 6 2019-07-05 09:00:23.840618      a  w    4
# 7 2019-07-05 09:00:23.840618      c  l    4
# 8 2019-07-05 07:00:23.840623      c  w    5
# 9 2019-07-05 07:00:23.840623      b  l    5

看,鉴于上述情况,我需要一个专栏,称之为“bta”代表“优于平均水平”,如下所示:

#                           gt player wl  gid   bta
# 0 2019-07-05 15:00:23.840588      a  w    1  True
# 1 2019-07-05 15:00:23.840588      b  l    1 False
# 2 2019-07-05 13:00:23.840605      a  w    2  True
# 3 2019-07-05 13:00:23.840605      c  l    2 False
# 4 2019-07-05 11:00:23.840611      a  w    3  True
# 5 2019-07-05 11:00:23.840611      b  l    3 False
# 6 2019-07-05 09:00:23.840618      a  w    4 False
# 7 2019-07-05 09:00:23.840618      c  l    4  True
# 8 2019-07-05 07:00:23.840623      c  w    5 False
# 9 2019-07-05 07:00:23.840623      b  l    5 False

无论我在哪里尝试set_index('game_t'),pandas都坚持索引必须是单调的。我知道game_t列在“总是增加”或“总是减少”的意义上不是单调的,因为它有重复项,分组索引应该是单调的,因为没有玩家在给定的时间玩一次以上。*

例如,以下内容:

df['bta'] = df.groupby('player').apply(lambda g: g.set_index('game_t').wl.eq('w').rolling('4.5h', min_periods=0).mean())

结果:

Traceback (most recent call last):....pandas internals stacktrace joy... ...ValueError: index must be monotonic

无论如何,我以前的尝试都没有任何价值,因为它们要么给出了错误的答案,要么触发了典型的“你不能从这里到达那里,你甚至尝试都有点愚蠢(你尝试过使用apply,尽管你可能是指transform”)显示错误消息。你知道吗

*旁白:开发人员不知道“单调”是什么意思,因为它实际上意味着“不变的,或不减的,或不增的”;单调既不意味着“增加”也不意味着“减少”。它们似乎意味着“严格增加或严格减少”


Tags: gamefalsetrue游戏dfindex时间玩家
1条回答
网友
1楼 · 发布于 2024-05-29 05:01:00

我不认为你的任何问题是个问题:

  1. game_t不是索引:将其设置为索引
  2. game_t不是单调的:排序它

这是我的解决办法

# sort values and set index
df = df.sort_values('game_t').set_index('game_t')

# if the player wins -> for rolling
df['is_win'] = df.wl.eq('w')

# closed='left' option skip the current game
win_mean = (df.groupby('player')
              .is_win.rolling('4.5H', closed='left')
              .mean().reset_index()
           )

df = df.reset_index().merge(win_mean, on = ['game_t', 'player'])
df['bta'] = df.is_win_y.gt(0.5)

df.sort_values(['gid', 'wl'], ascending=[True, False])

提供:

                      game_t player wl  gid  is_win_x  is_win_y    bta
8 2019-07-05 15:00:23.840588      a  w    1      True       1.0   True
9 2019-07-05 15:00:23.840588      b  l    1     False       0.0  False
6 2019-07-05 13:00:23.840605      a  w    2      True       1.0   True
7 2019-07-05 13:00:23.840605      c  l    2     False       0.0  False
4 2019-07-05 11:00:23.840611      a  w    3      True       1.0   True
5 2019-07-05 11:00:23.840611      b  l    3     False       0.0  False
2 2019-07-05 09:00:23.840618      a  w    4      True       NaN  False
3 2019-07-05 09:00:23.840618      c  l    4     False       1.0   True
0 2019-07-05 07:00:23.840623      c  w    5      True       NaN  False
1 2019-07-05 07:00:23.840623      b  l    5     False       NaN  False

如果愿意,可以删除这两列is_win。你知道吗

相关问题 更多 >

    热门问题