2015-11-04 47 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

相關問題