2017-03-08 158 views
3

我有一个熊猫数据帧包含格式日期:YYYY-MM-DD:排序日期

id1 = ['2015-09-23', '2014-07-08', '2015-07-30', '2008-09-26', 
     '2009-07-13', '2009-09-28', '2014-04-10', '2009-06-03'] 

id2 = ['2011-04-15', '2015-11-30', '2015-06-15', '2015-12-01', 
     '2015-12-23', '2009-01-14', '2009-06-17', '2009-08-07'] 

id3 = ['2010-01-26', '2010-03-16', '2011-11-23', '2012-01-31', 
     '2012-06-08', '2012-10-26', '2013-01-07', '2013-11-12'] 

df = pd.DataFrame({'dates':id1 + id2 + id3,'id':['id1']*8+['id2']*8+['id3']*8}) 

enter image description here

由此,我想第一个和最后一个日期为每个ID。

我试过如下:

df.groupby(['id'])['dates'].agg({'sort':sorted}) 

enter image description here

但问题是,我只能看到第一个日期,而不是最后一次。我希望有一个只有两个元素的输出列表:第一个和最后一个日期。而不是整个列表。

回答

6

易peasy

df.groupby('id').dates.agg({'date ': ['first', 'last']}) 
+0

有趣的,但似乎它的词典定义。提高列表中元素的顺序,而不是按日期排序。我想知道的是更早和最后的日期 –

+0

然后由最小和最大取代首先和最后。你可以接受我的解决方案,然后哈哈 –

+0

这是第一个,最后一个函数定义在哪里?熊猫吗? –

2

尝试:

df.groupby(['id']).apply(lambda x: [sorted(x['dates'])[0], 
            sorted(x['dates'])[-1]]) 

这需要排序两次,所以你可能要定义的lambda作为一个辅助功能。

2

您可以使用内置的第一个和最后

df.groupby(['id'])['dates'].agg(['first', 'last']) 

这让你

first  last 
id  
id1 2015-09-23 2009-06-03 
id2 2011-04-15 2009-08-07 
id3 2010-01-26 2013-11-12 
+1

你在开玩笑吗?这是我的解决方案 –

2

我从你离开的地方接走了,这里是您的解决方案只有两行和列表理解:

>>> new_df = df.groupby(['id'])['dates'].agg({'sort':sorted}) 
>>> new_df 
                sort 
id 
id1 [2008-09-26, 2009-06-03, 2009-07-13, 2009-09-2... 
id2 [2009-01-14, 2009-06-17, 2009-08-07, 2011-04-1... 
id3 [2010-01-26, 2010-03-16, 2011-11-23, 2012-01-3... 
>>> new_df['sort'] = [[lst[0], lst[-1]] for lst in new_df['sort'].tolist()] 
>>> new_df 
         sort 
id 
id1 [2008-09-26, 2015-09-23] 
id2 [2009-01-14, 2015-12-23] 
id3 [2010-01-26, 2013-11-12] 
>>> 
3
In[8]: df.groupby(['id']).dates.apply(lambda x: [min(x),max(x)]) 
Out[8]: 
id 
id1 [2008-09-26, 2015-09-23] 
id2 [2009-01-14, 2015-12-23] 
id3 [2010-01-26, 2013-11-12]