【问题标题】:pandas data frame aggregate a fixed number of rows熊猫数据框聚合固定数量的行
【发布时间】:2018-09-20 08:43:28
【问题描述】:

我正在处理一些数据,在这里我想获得每匹马最近跑步的排名 (finishing position)(跑步前最多 6 次跑步)。运行日期定义为'race_id'

有没有办法使用groupbyagg 但只聚合前6个值?

数据框如下:

finishing_position  horse_id    race_id
 1                  K01         2014011
 2                  K02         2014011
 3                  M01         2014011
 4                  K01         2014012
 2                  K01         2014021
 3                  K01         2014031
 1                  M01         2015011
 2                  K01         2016012
 1                  K02         2016012
 3                  M01         2016012
 4                  J01         2016012 

我希望结果是

finishing_position  horse_id    race_id     recent
 1                  K01         2014011
 2                  K02         2014011
 3                  M01         2014011
 4                  K01         2014012     1
 2                  K01         2014021     1/4
 3                  K01         2014031     1/4/2
 1                  M01         2015011     3
 2                  K01         2016012     1/4/2/3
 1                  K02         2016012     2
 3                  M01         2016012     3/1
 4                  J01         2016012   

【问题讨论】:

    标签: python sql pandas pandas-groupby


    【解决方案1】:

    我们可以使用cumsumgroupby

    df['recent']=df.finishing_position.astype(str)+'/'
    df['recent']=df.groupby('horse_id').recent.apply(lambda x : x.cumsum().shift().str[:-1].fillna(''))
    df
    Out[140]: 
        finishing_position horse_id  race_id   recent
    0                    1      K01  2014011         
    1                    2      K02  2014011         
    2                    3      M01  2014011         
    3                    4      K01  2014012        1
    4                    2      K01  2014021      1/4
    5                    3      K01  2014031    1/4/2
    6                    1      M01  2015011        3
    7                    2      K01  2016012  1/4/2/3
    8                    1      K02  2016012        2
    9                    3      M01  2016012      3/1
    10                   4      J01  2016012         
    

    【讨论】:

    • 谢谢,但是在哪里使 cumsum 只聚合到之前的 6 条记录?
    • 使用这个:select *, row_number() over(partition by horse_id order by race_id desc)racesback 然后过滤你想要的racesback
    • @goodBOB 似乎您需要滚动总和,但这与您预期的输出不匹配
    • @Wen 是的。我试过滚动总和,它总结了所有 6 个值。这是我的解决方案,我可以在 cumsum 之后摆脱新 df 上的额外排名。
    【解决方案2】:

    在@Wen 的答案上进行了修改,以仅聚合到以前的 N 条记录。

    df['recent']=df.finishing_position.astype(str)+'/'
    df['recent']=df.groupby('horse_id').recent.apply(lambda x : x.cumsum().shift().str[:-1].fillna(''))
    
    def last_n_record(string,recent_no):
        count = string.count('/')
        if count+1 >= recent_no:
           return string.split('/',count - recent_no + 1)[-1]
        else:
           return string
    
    recent_no = 3 # Lets take 3 recent records as demo
    df['recent'] = df.recent.apply(lambda x: last_n_record(x,recent_no))
    df
        finishing_position horse_id  race_id recent
    0                    1      K01  2014011       
    1                    2      K02  2014011       
    2                    3      M01  2014011       
    3                    4      K01  2014012      1
    4                    2      K01  2014021    1/4
    5                    3      K01  2014031  1/4/2
    6                    1      M01  2015011      3
    7                    2      K01  2016012  4/2/3
    8                    1      K02  2016012      2
    9                    3      M01  2016012    3/1
    10                   4      J01  2016012       
    

    【讨论】:

      猜你喜欢
      • 2022-01-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-04-01
      • 1970-01-01
      • 2016-06-24
      • 1970-01-01
      • 2019-08-02
      相关资源
      最近更新 更多