熊猫groupby列并获得N个滚动天数的总和和计数

时间:2019-09-19 03:18:42

标签: python pandas dataframe

我有一个具有以下结构的数据框:

        date           player_id  win
1       2018-08-01           1    0
2       2018-08-01           2    1
13      2018-08-01           2    1
37      2018-08-01           2    1
46      2018-08-01           1    0
54      2018-08-01           2    0
2074    2018-08-04           2    0
2082    2018-08-04           1    0
2093    2018-08-04           2    0
2094    2018-08-04           2    0
2109    2018-08-04           1    0
2118    2018-08-04           2    0
4419    2018-08-06           2    0
4427    2018-08-06           2    0
4492    2018-08-06           2    0
13361   2018-08-18           2    0
13375   2018-08-18           2    0
13395   2018-08-18           2    1
13412   2018-08-18           2    0
23963   2018-09-01           2    0
23976   2018-09-01           2    0
23988   2018-09-01           2    0
24001   2018-09-01           2    0
32695   2018-09-12           1    1
35355   2018-09-15           2    0
35361   2018-09-15           2    0

我需要能够获得每个player_id获胜栏的连续N天总和。

到目前为止,我已经在这里查看了答案,并尝试根据自己的需要对其进行修改。

pandas rolling sum of last five minutes

foo = pd.DataFrame( {'date': {1: '2018-08-01', 2: '2018-08-01', 13: '2018-08-01', 37: '2018-08-01', 46: '2018-08-01', 54: '2018-08-01', 2074: '2018-08-04', 2082: '2018-08-04', 2093: '2018-08-04', 2094: '2018-08-04', 2109: '2018-08-04', 2118: '2018-08-04', 4419: '2018-08-06', 4427: '2018-08-06', 4492: '2018-08-06', 13361: '2018-08-18', 13375: '2018-08-18', 13395: '2018-08-18', 13412: '2018-08-18', 23963: '2018-09-01', 23976: '2018-09-01', 23988: '2018-09-01', 24001: '2018-09-01', 32695: '2018-09-12', 35355: '2018-09-15', 35361: '2018-09-15'}, 'player_id': {1: 10946, 2: 24223, 13: 24223, 37: 24223, 46: 10946, 54: 24223, 2074: 24223, 2082: 10946, 2093: 24223, 2094: 24223, 2109: 10946, 2118: 24223, 4419: 24223, 4427: 24223, 4492: 24223, 13361: 24223, 13375: 24223, 13395: 24223, 13412: 24223, 23963: 24223, 23976: 24223, 23988: 24223, 24001: 24223, 32695: 10946, 35355: 24223, 35361: 24223}, 'win': {1: 0, 2: 1, 13: 1, 37: 1, 46: 0, 54: 0, 2074: 0, 2082: 0, 2093: 0, 2094: 0, 2109: 0, 2118: 0, 4419: 0, 4427: 0, 4492: 0, 13361: 0, 13375: 0, 13395: 1, 13412: 0, 23963: 0, 23976: 0, 23988: 0, 24001: 0, 32695: 1, 35355: 0, 35361: 0}} )
foo

foo['date'] = pd.to_datetime(foo['date'])
foo['end_index'] = np.arange(len(foo))
start_dates = foo['date'] - pd.Timedelta(days=30)
foo['start_index'] = foo['date'].values.searchsorted(start_dates, side='right')

bar = foo[foo['player_id'] == 2]
def sum_window(row):
    return bar['win'].iloc[row['start_index']:row['end_index']+1].sum()    
bar['rolling_wins'] = bar.apply(sum_window, axis=1)
bar['rolling_wins'] = bar.groupby('player_id')['rolling_wins'].shift(1)
bar

产生

            date  player_id  win  end_index  start_index  rolling_wins
2     2018-08-01          2    1          1            0           NaN
13    2018-08-01          2    1          2            0           2.0
37    2018-08-01          2    1          3            0           3.0
54    2018-08-01          2    0          5            0           3.0
2074  2018-08-04          2    0          6            0           3.0
2093  2018-08-04          2    0          8            0           3.0
2094  2018-08-04          2    0          9            0           3.0
2118  2018-08-04          2    0         11            0           3.0
4419  2018-08-06          2    0         12            0           3.0
4427  2018-08-06          2    0         13            0           3.0
4492  2018-08-06          2    0         14            0           4.0
13361 2018-08-18          2    0         15            0           4.0
13375 2018-08-18          2    0         16            0           4.0
13395 2018-08-18          2    1         17            0           4.0
13412 2018-08-18          2    0         18            0           4.0
23963 2018-09-01          2    0         19            6           4.0
23976 2018-09-01          2    0         20            6           1.0
23988 2018-09-01          2    0         21            6           1.0
24001 2018-09-01          2    0         22            6           1.0
35355 2018-09-15          2    0         24           15           1.0
35361 2018-09-15          2    0         25           15           0.0

这很好用,并且仅给出bar的滚动总和。我需要为rolling_games N计数添加一列。

除此之外,我还需要将其包装在一个很好的整齐函数中,以便我可以运行foo.groupby('player_id').apply(func)

我在上面尝试过这种方法,但是遇到了问题。我认为速度将是一个问题,因为我需要在其中运行的数据集包含成千上万的玩家和成千上万的游戏。

任何建议/帮助都将受到欢迎和赞赏。

亲切的问候,

卢克

0 个答案:

没有答案