2014-07-24 188 views
2

第二小值,我有一个例子数据框类似如下:Python的大熊猫:选择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)) 

结果是错误的。

你能找到一种方法使这项工作?

+2

使用nsmallest,加入0.14.1:https://github.com/pydata/pandas/pull/7356 – Jeff

回答

4

这需要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] 
+0

你也可以通过一个列表 – Jeff

3

看看索引docs - 一般熊猫默认使用标签索引而不是位置索引 - 这就是为什么你会得到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] 
+0

约'.iloc'与'的文档的特定部分.loc' [这里] (http://pandas.pydata.org/pandas-docs/stable/indexing.html#different-choices-for-indexing-loc-iloc-and-ix)。 – jmduke