熊猫-获得每个用户的平均周数

时间:2018-08-11 20:57:39

标签: python pandas dataframe

我正试图弄清楚如何获取代表游戏中玩家的数据框,该数据框具有唯一的用户以及特定用户每天活跃的记录。

我正在尝试获取各个用户生命周期中每个星期的平均游戏时间平均移动

(星期由用户的第一条记录定义,即,如果用户的第一条记录是1月3日,则他们的第一周从1月10日开始,第二周从1月10日开始)。

>

示例

userid                          date          secondsPlayed   movesMade
++/acsbP2NFC2BvgG1BzySv5jko=    2016-04-28    413.88188       85
++/acsbP2NFC2BvgG1BzySv5jko=    2016-05-01    82.67343        15
++/acsbP2NFC2BvgG1BzySv5jko=    2016-05-05    236.73809       39
++/acsbP2NFC2BvgG1BzySv5jko=    2016-05-10    112.69112       29
++/acsbP2NFC2BvgG1BzySv5jko=    2016-05-11    211.42790       44
-----------------------------------CONT----------------------------------
++/8ij1h8378h123123koF3oer1    2016-05-05     200.73809       11
++/8ij1h8378h123123koF3oer1    2016-05-10     51.69112        14
++/8ij1h8378h123123koF3oer1    2016-05-14     65.42790        53

最终结果将是下表:

userid                          date        secondsPlayed_w movesMade_w
++/acsbP2NFC2BvgG1BzySv5jko=    2016-04-28    496.55531       100
++/acsbP2NFC2BvgG1BzySv5jko=    2016-05-05    236.73809       68    
-----------------------------------CONT----------------------------------
++/8ij1h8378h123123koF3oer1    2016-05-05     252.42921       25    
++/8ij1h8378h123123koF3oer1    2016-05-12     65.42790        53

失败的尝试1:

到目前为止,我已经尝试做很多不同的事情,但是我设法创建的最有用的数据框如下:


    df_grouped = df.groupby('userid').apply(lambda x: x.set_index('date').resample('1D').first().fillna(0))
    df_result = df_grouped.groupby(level=0)['secondsPlayed'].apply(lambda x: x.rolling(min_periods=1, window=7).mean()).reset_index(name='secondsPlayed_week')

这是一个非常缓慢且浪费的计算,但是仍然可以用作中间步骤。

userid                          date        secondsPlayed_w
++/acsbP2NFC2BvgG1BzySv5jko=    2016-04-28  4.138819e+02
++/acsbP2NFC2BvgG1BzySv5jko=    2016-04-29  2.069409e+02    
++/acsbP2NFC2BvgG1BzySv5jko=    2016-04-30  1.379606e+02    
++/acsbP2NFC2BvgG1BzySv5jko=    2016-05-01  1.241388e+02    
++/acsbP2NFC2BvgG1BzySv5jko=    2016-05-02  9.931106e+01    
++/acsbP2NFC2BvgG1BzySv5jko=    2016-05-03  8.275922e+01    
++/acsbP2NFC2BvgG1BzySv5jko=    2016-05-04  7.093647e+01    
++/acsbP2NFC2BvgG1BzySv5jko=    2016-05-05  4.563022e+01

尝试#2失败:  

df_result = (df
    .reset_index()
    .set_index("date")
    .groupby(pd.Grouper(freq='W'))).agg({"userid":"first", "secondsPlayed":"sum", "movesUsed":"sum"})
    .reset_index()

哪个给了我以下数据帧,它的缺点是没有按用户标识分组(NaN问题很容易解决)。

date        userid                        secondsPlayed_w   movesMade_w
2016-04-10  +1kexX0Yk2Su639WaRKARcwjq5g=    2.581356e+03    320
2016-04-17  +1kexX0Yk2Su639WaRKARcwjq5g=    4.040738e+03    615
2016-04-24   NaN                             0.000000e+00   0
2016-05-01  ++RBPf9KdTK6pTN+lKZHDLCXg10=    1.644130e+05    17453
2016-05-08  ++DndI7do036eqYh9iW7vekAnx0=    3.775905e+05    31997
2016-05-15  ++NjKpr/vyxNCiYcmeFK9qSqD9o=    4.993430e+05    34706
2016-05-22  ++RBPf9KdTK6pTN+lKZHDLCXg10=    3.940408e+05    23779

即时想法:

可以通过使用由两列分组的groupby来解决此问题。但是我完全不确定如何解决这个特定问题。

2 个答案:

答案 0 :(得分:3)

您可以创建新的帮助groupby

df.date=pd.to_datetime(df.date)
df['Newweeknumber']=df.groupby('userid').date.diff().dt.days.cumsum().fillna(0)//7# get the week number by the first date of each id
df.groupby(['userid','Newweeknumber']).agg({"userid":"first", "secondsPlayed":"sum", "movesMade":"sum"})

答案 1 :(得分:1)

更新

尝试

df1 = pd.DataFrame(index=pd.date_range('2015-04-24', periods = 50)).assign(value=1)
df2 = pd.DataFrame(index=pd.date_range('2015-04-28', periods = 50)).assign(value=1)

df3 = pd.concat([df1,df2], keys=['A','B'])

df3 = df3.rename_axis(['user','date']).reset_index()

df3.groupby('user').apply(lambda x: x.resample('7D', on='date').sum())

输出:

                 value
user date             
A    2015-04-24      7
     2015-05-01      7
     2015-05-08      7
     2015-05-15      7
     2015-05-22      7
     2015-05-29      7
     2015-06-05      7
     2015-06-12      1
B    2015-04-28      7
     2015-05-05      7
     2015-05-12      7
     2015-05-19      7
     2015-05-26      7
     2015-06-02      7
     2015-06-09      7
     2015-06-16      1