计算每组的滚动总和

时间:2019-01-12 19:20:47

标签: python pandas dataframe group-by pandas-groupby

我的目标是进行分组,然后创建汇总统计数据,然后进行轮换。我需要它来转移每个唯一玩家的第一个实例。现在,它只移动整个数据帧一次,而不是为每个分组的播放器移动。

原始数据-

    player   date          won
0   A        2016-01-11    0
1   A        2016-02-01    0
2   A        2016-02-01    1
3   A        2016-02-01    1
4   A        2016-10-24    0
5   A        2016-10-31    0
6   A        2018-10-22    0
7   B        2016-10-24    0
8   B        2016-10-24    1
9   B        2017-11-13    0  

我尝试过的事情-

1

temp = temp_master.groupby('player', sort=False)[count_fields].rolling(10, min_periods=1).sum().shift(1).reset_index(drop=True)    
temp = temp.add_suffix('_total')   
temp['won_total'].head(10)  
 0    NaN
 1    0.0
 2    0.0
 3    1.0
 4    2.0
 5    2.0
 6    2.0
 7    2.0
 8    0.0
 9    1.0

2

temp = temp_master.groupby('player', sort=False)[count_fields].shift(1).rolling(10, min_periods=1).sum().reset_index(drop=True) 
temp = temp.add_suffix('_total') 
temp['won_total'].head(10)
0    NaN
1    0.0
2    0.0
3    1.0
4    2.0
5    2.0
6    2.0
7    2.0
8    2.0
9    3.0 

3

temp = temp_master.groupby('player', sort=False)[count_fields].rolling(10, min_periods=1).sum().reset_index(drop=True)    
temp = temp.add_suffix('_total')
temp = temp.shift(1)  
temp['won_total'].head(10)  
0    NaN
1    0.0
2    0.0
3    1.0
4    2.0
5    2.0
6    2.0
7    2.0
8    0.0
9    1.0

这就是我需要的结果-

0    NaN
1    0.0
2    0.0
3    1.0
4    2.0
5    2.0
6    2.0
7    NaN
8    0.0
9    1.0

索引7应该等于NaN。它应该是玩家B的第一个实例,我希望它在每个新玩家的第一个实例上转移以按玩家召集统计信息。

索引8应该等于0

索引9应该等于1

尝试#1和#3似乎已结束,但未在新播放器上分配NaN值。 #3不再做分组球员了,所以我知道那真的行不通。

此外,这将在大量数据(大约100K-300K行)上完成,并且“ count_fields”列包含我正在计算的大约3K-4K列。只是要注意的事情。

关于如何按玩家创建跑步统计信息并为每个玩家调低位置的任何想法?

2 个答案:

答案 0 :(得分:2)

您在这里需要apply,这两个函数不在groupby对象下链,sum在groupby下,但是shift将对求和后的结果执行整列

temp = temp_master.groupby('player', sort=False)['won'].apply(lambda x : x.rolling(10, min_periods=1).sum().shift(1))\
    .reset_index(drop=True)    
temp
0    NaN
1    0.0
2    0.0
3    1.0
4    2.0
5    2.0
6    2.0
7    NaN
8    0.0
9    1.0
Name: won, dtype: float64

答案 1 :(得分:2)

如果您不想使用apply,另一种选择是层叠第二个groupby呼叫并执行转移:

(df.groupby('player', sort=False)
   .won.rolling(10, min_periods=1)
   .sum()
   .groupby(level=0)
   .shift()
   .reset_index(drop=True))

0    NaN
1    0.0
2    0.0
3    1.0
4    2.0
5    2.0
6    2.0
7    NaN
8    0.0
9    1.0
Name: won, dtype: float64