Python pandas:在groupby中选择第二小的值
我有一个示例数据表,长得像这样:
import pandas as pd
import numpy as np
df = pd.DataFrame({'ID':[1,2,2,2,3,3,], 'date':array(['2000-01-01','2002-01-01','2010-01-01','2003-01-01','2004-01-01','2008-01-01'],dtype='datetime64[D]')})
我想要找出每个ID组中第二早的日期。所以我写了下面这个函数:
def f(x):
if len(x)==1:
return x[0]
else:
x.sort()
return x[1]
然后我又写了:
df.groupby('ID').date.apply(lambda x:f(x))
结果却出现了错误。
你能帮我想办法让它正常工作吗?
3 个回答
1
你可能不想把第一个也是唯一的值当作第二个值,就像在被接受的答案中那样(也就是说,2000-01-01
不是第二个值,而是唯一的值)。如果是这种情况,你可以对每个组进行排名,这样就能更通用地选择第一个、第二个、第三个等最小值:
df['rank'] = df.sort_values('date').groupby('ID').cumcount()+1
要获取第二小的值:
df[df['rank'] == 2]
这将返回
ID date rank
2 2003-01-01 2
3 2008-01-01 2
3
看看这个索引的文档 - 一般来说,pandas 默认是通过标签来索引数据,而不是通过位置来索引,这就是你遇到 KeyError
的原因。
在你的具体情况下,你可以使用 .iloc
来进行基于位置的索引。
In [266]: def f(x):
...: if len(x)==1:
...: return x.iloc[0]
...: else:
...: x.sort()
...: return x.iloc[1]
...:
In [267]: df.groupby('ID').date.apply(f)
Out[267]:
ID
1 2000-01-01
2 2003-01-01
3 2008-01-01
Name: date, dtype: datetime64[ns]
7
这个需要版本0.14.1。这样做会非常高效,特别是当你有很多数据组的时候,因为它不需要对这些数据进行完全排序。
In [32]: df.groupby('ID')['date'].nsmallest(2)
Out[32]:
ID
1 0 2000-01-01
2 1 2002-01-01
3 2003-01-01
3 4 2004-01-01
5 2008-01-01
dtype: datetime64[ns]
In [33]: df.groupby('ID')['date'].nsmallest(2).groupby(level='ID').last()
Out[33]:
ID
1 2000-01-01
2 2003-01-01
3 2008-01-01
dtype: datetime64[ns]