如何在不考虑额外列的情况下保留每个类别的最早记录?

How to keep earliest record for each category but without considering the extra columns?

假设我有一个包含 3 列的数据 table:

Category             Color              Date
triangle             red                2017-10-10
square               yellow             2017-11-10
triangle             blue               2017-02-10
circle               yellow             2017-07-10
circle               red                2017-09-10

我想按每个类别找出最早的日期。 所以我想要的输出是:

Category             Color              Date
square               yellow             2017-11-10
triangle             blue               2017-02-10
circle               yellow             2017-07-10

我浏览了几篇关于如何执行此操作的帖子:

Finding the min date in a Pandas DF row and create new Column

还有更多。

一种流行的方法是 groupby 方法:

df.groupby('Category').first().reset_index() 

但是如果我使用这种方法,那么它将按 Category 分组,但它会保留 triangle 的两条记录,因为它有两种不同的颜色。

有没有更好更有效的方法呢?

您可以使用 sort_values + drop_duplicates:

df.sort_values(['Date']).drop_duplicates('Category', keep='first')

   Category   Color        Date
2  triangle    blue  2017-02-10
3    circle  yellow  2017-07-10
1    square  yellow  2017-11-10

如果您想保留 Category 的原始顺序,您需要对 groupby 调用进行排序:

df.groupby('Category', group_keys=False, sort=False)\
  .apply(lambda x: x.sort_values('Date'))\
  .drop_duplicates('Category', keep='first')

   Category   Color        Date
2  triangle    blue  2017-02-10
1    square  yellow  2017-11-10
3    circle  yellow  2017-07-10

下面应该会给你想要的输出;与您发布的内容进行比较,我首先根据日期对值进行排序,因为您希望保留每个类别的最早日期:

df.sort_values('Date').groupby('Category').first().reset_index()

这给出了所需的输出:

   Category   Color        Date
0    circle  yellow  2017-07-10
1    square  yellow  2017-11-10
2  triangle    blue  2017-02-10

编辑

感谢评论中的@Wen,通过以下方式也可以提高此调用的效率:

df.sort_values('Date').groupby('Category', as_index=False).first()

这也给出了

   Category   Color        Date
0    circle  yellow  2017-07-10
1    square  yellow  2017-11-10
2  triangle    blue  2017-02-10

head 将 return 你原来的专栏

df.sort_values(['Date']).groupby('Category').head(1)
Out[156]: 
   Category   Color        Date
2  triangle    blue  2017-02-10
3    circle  yellow  2017-07-10
1    square  yellow  2017-11-10

nth 还有:

df.sort_values(['Date']).groupby('Category',as_index=False).nth(0)
Out[158]: 
   Category   Color        Date
2  triangle    blue  2017-02-10
3    circle  yellow  2017-07-10
1    square  yellow  2017-11-10

idxmin

df.loc[df.groupby('Category').Date.idxmin()]
Out[166]: 
   Category   Color       Date
3    circle  yellow 2017-07-10
1    square  yellow 2017-11-10
2  triangle    blue 2017-02-10