【问题标题】:Get only the first and last rows of each group with pandas只用 pandas 获取每组的第一行和最后一行
【发布时间】:2019-05-24 10:36:59
【问题描述】:

我是 python 的新手。我有一个巨大的dataframe,有数百万行和 id。我的数据如下所示:

Time    ID  X   Y
8:00    A   23  100
9:00    B   24  110
10:00   B   25  120
11:00   C   26  130
12:00   C   27  140
13:00   A   28  150
14:00   A   29  160
15:00   D   30  170
16:00   C   31  180
17:00   B   32  190
18:00   A   33  200
19:00   C   34  210
20:00   A   35  220
21:00   B   36  230
22:00   C   37  240
23:00   B   38  250

我想按 id 和 time 对数据进行排序。我想要的预期结果是这样的”

Time    ID  X   Y
8:00    A   23  100
13:00   A   28  150
14:00   A   29  160
18:00   A   33  200
20:00   A   35  220
9:00    B   24  110
10:00   B   25  120
17:00   B   32  190
21:00   B   36  230
23:00   B   38  250
11:00   C   26  130
12:00   C   27  140
16:00   C   31  180
19:00   C   34  210
22:00   C   37  240
15:00   D   30  170

我只想选择 id 的“第一个和最后一个”并消除其余部分。预期结果如下所示:

Time    ID  X   Y
8:00    A   23  100
20:00   A   35  220
9:00    B   24  110
23:00   B   38  250
11:00   C   26  130
22:00   C   37  240
15:00   D   30  170

如何在熊猫中做到这一点?谢谢你的建议

【问题讨论】:

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


    【解决方案1】:

    使用groupby,找到每个组的headtail,以及concat 两者。

    g = df.groupby('ID')
    
    (pd.concat([g.head(1), g.tail(1)])
       .drop_duplicates()
       .sort_values('ID')
       .reset_index(drop=True))
    
        Time ID   X    Y
    0   8:00  A  23  100
    1  20:00  A  35  220
    2   9:00  B  24  110
    3  23:00  B  38  250
    4  11:00  C  26  130
    5  22:00  C  37  240
    6  15:00  D  30  170
    

    如果您能保证每个 ID 组有至少两行,则不需要drop_duplicates 调用。


    详情

    g.head(1)
    
        Time ID   X    Y
    0   8:00  A  23  100
    1   9:00  B  24  110
    3  11:00  C  26  130
    7  15:00  D  30  170
    
    g.tail(1)
    
         Time ID   X    Y
    7   15:00  D  30  170
    12  20:00  A  35  220
    14  22:00  C  37  240
    15  23:00  B  38  250
    
    pd.concat([g.head(1), g.tail(1)])
    
         Time ID   X    Y
    0    8:00  A  23  100
    1    9:00  B  24  110
    3   11:00  C  26  130
    7   15:00  D  30  170
    7   15:00  D  30  170
    12  20:00  A  35  220
    14  22:00  C  37  240
    15  23:00  B  38  250
    

    【讨论】:

    • 令人印象深刻..你介意向我解释一下pd.concatgroupby中的功能是什么吗?
    • @Arief g.head(1)g.tail(1) 返回两个单独的数据帧;然后我使用pd.concat 将两个DataFrame 垂直连接在一起。 concatgroupby 是独立的操作。
    • 非常感谢您提供更详细的解释。如何保存到新的csv?因为我尝试了to.csv 我得到了错误。
    • @Arief result.to_csv('file.csv')。如果有帮助记得采纳答案,谢谢:-)
    • 如何考虑按时间和ID排序?因为我尝试了我的数据,我对时间数据感到困惑。
    【解决方案2】:

    如果您创建一个小函数来仅选择 DataFrame 的第一行和最后一行,则可以将其应用于 group-by,如下所示:

    df.groupby('ID').apply(lambda x: df.iloc[[0, -1]])
    

    正如其他人所提到的,在“ID”只有一行的情况下,也可以使用.drop_duplicates() 或类似名称过滤掉重复的行。

    【讨论】:

      猜你喜欢
      • 2014-09-29
      • 2014-11-10
      • 2019-05-12
      • 2011-03-27
      • 2021-04-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多