2015-11-04 65 views
4

我最近必须获取某些项目的最后设置状态,并标有ID。我发现这个答案:Python : How can I get Rows which have the max value of the group to which they belong?从熊猫数据框中获取最后条目的最佳方式

令我惊讶的是只有~2e6行的数据集相当慢。但是,我不需要获取所有最大值,只有最后一个值。

import numpy as np 
import pandas as pd 

df = pd.DataFrame({ 
    "id": np.random.randint(1, 1000, size=5000), 
    "status": np.random.randint(1, 10, size=5000), 
    "date": [ 
     time.strftime("%Y-%m-%d", time.localtime(time.time() - x)) 
     for x in np.random.randint(-5e7, 5e7, size=5000) 
    ], 
}) 

%timeit df.groupby('id').apply(lambda t: t[t.date==t.date.max()]) 
1 loops, best of 3: 576 ms per loop 

%timeit df.reindex(df.sort_values(["date"], ascending=False)["id"].drop_duplicates().index) 
100 loops, best of 3: 4.82 ms per loop 

第一个是我在链接中找到的解决方案,这似乎是一种允许更复杂操作的方法。

但是,对于我的问题,我可以排序和删除重复项和reindex,这表现更好。特别是在较大的数据集上,这确实有所作为。

我的问题:还有其他方法可以实现我想要做的吗?可能具有更好的性能?

+0

一个评论:串排序是不是数字排序慢,这样你就可以在第二种解决方案中,首先将日期列转换为日期时间类型:''df ['date'] = pd.to_datetime(df ['date'])'' – jakevdp

回答

1

解决此问题的另一种方法是在groupby上使用聚合,然后在完整数据框上进行选择。

df.iloc[df.groupby('id')['date'].idxmax()] 

这似乎比您提出的解决方案快5-10倍(见下文)。请注意,如果'date'列是数字,而不是字符串类型,这只会工作,而这种转变也加快了您的基于排序的解决方案:

# Timing your original solutions: 
%timeit df.groupby('id').apply(lambda t: t[t.date==t.date.max()]) 
# 1 loops, best of 3: 826 ms per loop 
%timeit df.reindex(df.sort_values(["date"], ascending=False)["id"].drop_duplicates().index) 
# 100 loops, best of 3: 5.1 ms per loop 

# convert the date 
df['date'] = pd.to_datetime(df['date']) 

# new times on your solutions 
%timeit df.groupby('id').apply(lambda t: t[t.date==t.date.max()]) 
# 1 loops, best of 3: 815 ms per loop 
%timeit df.reindex(df.sort_values(["date"], ascending=False)["id"].drop_duplicates().index) 
# 1000 loops, best of 3: 1.99 ms per loop 

# my aggregation solution 
%timeit df.iloc[df.groupby('id')['date'].idxmax()] 
# 10 loops, best of 3: 135 ms per loop 
+0

在我的原始数据中,日期那里已经是datetime64,但有用的信息就更少了。聚合解决方案在我的原始数据(3分40秒)上给出了可接受的性能,在这种情况下可行。这肯定会帮助我处理更复杂的情况,即排序和删除重复项目不会提供所需的结果。谢谢!也用于快速响应。 – galinden

相关问题