基于多列的groupby删除行,仅产生最低值

时间:2017-06-04 17:09:00

标签: python pandas dataframe

我在Python中的pandas数据框中有以下数据。我想基于Name和Property列对数据进行分组,并且只保留Date中的最低值。

在:

  Name  Property                         Date
0   X1      Cash  621 days 00:00:00.000000000
1   X1      Cash  256 days 00:00:00.000000000
2   X1      Cash  101 days 00:00:00.000000000
3   X1  Overflow  352 days 00:00:00.000000000
4   X1  Overflow  101 days 00:00:00.000000000
5   X1  Overflow   53 days 00:00:00.000000000

重复X2 / X3等。

后:

  Name  Property                         Date
2   X1      Cash  101 days 00:00:00.000000000
5   X1  Overflow   53 days 00:00:00.000000000

我正在尝试使用语法,但无法正确使用它:

df1 = df1[df1.groupby(['Name', 'Property'])['Date'].min()]

2 个答案:

答案 0 :(得分:4)

如果您在groupby.min()结果上调用reset intex,您将获得所需的输出:

df.groupby(['Name', 'Property'])['Date'].min().reset_index()
Out: 
  Name  Property     Date
0   X1      Cash 101 days
1   X1  Overflow  53 days

您还可以使用nsmallest

df.groupby(['Name', 'Property'])['Date'].nsmallest(1)
Out: 
Name  Property   
X1    Cash      2   101 days
      Overflow  5    53 days
Name: Date, dtype: timedelta64[ns]

如果需要,您可以重置索引并删除原始索引:

df.groupby(['Name', 'Property'])['Date'].nsmallest(1).reset_index(level=[0, 1])
Out: 
  Name  Property     Date
2   X1      Cash 101 days
5   X1  Overflow  53 days

如果您想要保留其他列,则可以使用多个选项。

df['additional column'] = np.arange(6)

df
Out: 
  Name  Property     Date  additional column
0   X1      Cash 621 days                  0
1   X1      Cash 256 days                  1
2   X1      Cash 101 days                  2
3   X1  Overflow 352 days                  3
4   X1  Overflow 101 days                  4
5   X1  Overflow  53 days                  5

正如@piRSquared所提到的,第一个是使用loc和返回行的索引:

df.loc[df.groupby(['Name', 'Property'])['Date'].idxmin()]

第二个是合并原始DataFrame和聚合的:

df.merge(df.groupby(['Name', 'Property'])['Date'].min().reset_index())

两者都屈服:

  Name  Property     Date  additional column
0   X1      Cash 101 days                  2
1   X1  Overflow  53 days                  5

根据用例,可能会胜过另一个。

答案 1 :(得分:1)

您可以在transform中尝试pandas,也不会删除其他列。

DF = df[df.groupby(['Property'])['Date'].transform(min) == df['Date']]



   Name Property    Date

2   X1  Cash        101 days

5   X1  Overflow    53  days