【问题标题】:Pandas - Get week average for each userPandas - 获取每个用户的每周平均值
【发布时间】:2018-08-11 20:57:39
【问题描述】:

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

我正在尝试获取不同用户生命周期中每周平均游戏时间平均移动

(周由用户的第一条记录定义,即如果用户的第一条记录是 1 月 3 日,则他们的第一周开始,第二周开始 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()

这给了我以下数据框,它的错误是没有按用户 ID 分组(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 来解决此问题。但我完全不确定如何解决这个特殊问题。

【问题讨论】:

    标签: python pandas dataframe


    【解决方案1】:

    您可以创建一个newid帮助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"})
    

    【讨论】:

    • 非常感谢@Wen 的回答!我喜欢 weeknumber 帮助的想法,但是结果(如以下数据框中所示:link ),不幸的是似乎并没有在几周内总结。它似乎只是在现有日期值之上添加了周数。也意味着不会出现没有条目的周。
    【解决方案2】:

    更新

    试试

    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
    

    【讨论】:

    • 非常感谢@Scott,这几乎解决了我的问题!唯一的问题是 freq='7D' 的 grouper 似乎不是按组中的第一个日期分组,而是按组对应周的第一个星期日分组。
    • 即分组前第一个条目的日期为:2016-04-28,分组后的第一个条目的日期为:2016-04-24
    • 好吧,我很困惑。您要按星期天到星期六的周分组,还是按接下来的 7 天分组?
    • 我想你第一次完全正确地理解了我,从每个用户进入的第一个日期开始是 7 天。但是,这似乎不是我的数据生成的数据框。使用 freq="7D" 时,我总是以周日到周六的分组结束。
    • @ThomasHeiberg 好的,如果我现在明白了,让我们分组然后使用 resample 和 freq='7D'。在这里,您得到两组,每个 7D 总和从该组的第一天开始。
    猜你喜欢
    • 2020-03-09
    • 1970-01-01
    • 1970-01-01
    • 2018-11-20
    • 2016-03-28
    • 1970-01-01
    • 2015-06-01
    • 1970-01-01
    • 2021-01-30
    相关资源
    最近更新 更多