Python 按第一个值对组进行排序,而不更改组顺序

Python 按第一个值对组进行排序,而不更改组顺序,python,pandas,dataframe,group-by,pandas-groupby,Python,Pandas,Dataframe,Group By,Pandas Groupby,我试图在不改变块内顺序的情况下按块对数据帧进行排序 dataframe包含论坛帖子、时间戳和线程名称。我已经使用df.sort_值(['thread',timestamp',inplace=True)对数据帧进行了排序,以便属于同一线程的所有帖子都按正确的顺序排列。现在,我想根据每个块中第一个post的时间戳对属于同一线程的数据块进行排序。块内的顺序应保持不变 我目前拥有的: post timestamp thread 0 this 2009/10/30 16

我试图在不改变块内顺序的情况下按块对数据帧进行排序

dataframe包含论坛帖子、时间戳和线程名称。我已经使用
df.sort_值(['thread',timestamp',inplace=True)对数据帧进行了排序,以便属于同一线程的所有帖子都按正确的顺序排列。现在,我想根据每个块中第一个post的时间戳对属于同一线程的数据块进行排序。块内的顺序应保持不变

我目前拥有的:

    post   timestamp         thread
0   this   2009/10/30 16:51  hello   
1   be     2009/11/02 17:11  hello
2   some   2008/07/10 15:23  nice
3   text   2007/04/22 14:11  question
4   this   2007/04/24 11:03  question
5   be     2007/05/03 17:55  question
6   some   2004/09/01 09:32  game
7   text   2010/01/01 03:32  wheather
我想要的是:

    post   timestamp         thread
6   some   2004/09/01 09:32  game
3   text   2007/04/22 14:11  question
4   this   2007/04/24 11:03  question
5   be     2007/05/03 17:55  question
2   some   2008/07/10 15:23  nice
0   this   2009/10/30 16:51  hello   
1   be     2009/11/02 17:11  hello
7   text   2010/01/01 03:32  wheather
有办法做到这一点吗

  • 首先,获取每个组的第一个“时间戳”并
    argsort
    it
  • 接下来,使用
    groupby
    ,利用
    groupby
    按键对组进行排序,但不更改组内的顺序这一事实
  • 最后,
    concat

  • 一种方法是在“线程”上创建一个名为“first_ts”的临时列,其中包含
    groupby
    ,并在每个线程的“timestamp”列上获取
    min
    (so first date)。现在,您可以按此列对值进行排序,然后删除临时列

    # you might need to convert timestamp to datetime 
    df.timestamp = pd.to_datetime(df.timestamp)
    #create the column
    df['first_ts'] = df.groupby('thread').timestamp.transform(min)
    #sort and drop
    df = df.sort_values(['first_ts']).drop('first_ts',axis=1)
    
    你得到了预期的结果

    print(df)
       post           timestamp    thread
    6  some 2004-09-01 09:32:00      game
    3  text 2007-04-22 14:11:00  question
    4  this 2007-04-24 11:03:00  question
    5    be 2007-05-03 17:55:00  question
    2  some 2008-07-10 15:23:00      nice
    0  this 2009-10-30 16:51:00     hello
    1    be 2009-11-02 17:11:00     hello
    7  text 2010-01-01 03:32:00  wheather
    
    或者,如果不想创建列,也可以使用
    reindex
    groupby
    的排序值索引,例如:

    df = df.reindex(df.groupby('thread').timestamp.transform(min)
                      .sort_values().index)
    

    让我们首先尝试
    groupby
    线程,然后获取第一条记录,按时间对这些记录进行排序,然后使用DataFrameGroupBy的
    groups
    属性获取每个组中索引的当前顺序。最后,使用
    pd.concat
    和列表理解按第一条记录的排序顺序重建数据帧

    g = df.groupby('thread')
    s = g.head(1).sort_values('timestamp')['thread']
    dg = g.groups
    
    pd.concat([df.reindex(dg[i[1]]) for i in s.iteritems()])
    
    输出:

       post           timestamp    thread
    6  some 2004-09-01 09:32:00      game
    3  text 2007-04-22 14:11:00  question
    4  this 2007-04-24 11:03:00  question
    5    be 2007-05-03 17:55:00  question
    2  some 2008-07-10 15:23:00      nice
    0  this 2009-10-30 16:51:00     hello
    1    be 2009-11-02 17:11:00     hello
    7  text 2010-01-01 03:32:00  wheather
    

    使用
    sort_value
    drop_duplicates
    获得最小值,然后使用
    Categorical

    cate=df.sort_values('timestamp').drop_duplicates('thread')
    df.thread=pd.Categorical(df.thread,ordered=True,categories=cate.thread.tolist())
    df=df.sort_values('thread')
    df
       post           timestamp    thread
    6  some 2004-09-01 09:32:00      game
    3  text 2007-04-22 14:11:00  question
    4  this 2007-04-24 11:03:00  question
    5    be 2007-05-03 17:55:00  question
    2  some 2008-07-10 15:23:00      nice
    0  this 2009-10-30 16:51:00     hello
    1    be 2009-11-02 17:11:00     hello
    7  text 2010-01-01 03:32:00  wheather
    
    cate=df.sort_values('timestamp').drop_duplicates('thread')
    df.thread=pd.Categorical(df.thread,ordered=True,categories=cate.thread.tolist())
    df=df.sort_values('thread')
    df
       post           timestamp    thread
    6  some 2004-09-01 09:32:00      game
    3  text 2007-04-22 14:11:00  question
    4  this 2007-04-24 11:03:00  question
    5    be 2007-05-03 17:55:00  question
    2  some 2008-07-10 15:23:00      nice
    0  this 2009-10-30 16:51:00     hello
    1    be 2009-11-02 17:11:00     hello
    7  text 2010-01-01 03:32:00  wheather