簡體   English   中英

如何提高對熊貓數據框的聚合操作的速度?

[英]How to improve the speed of an aggregate operation on a pandas dataframe?

我有一個名為data_1的熊貓數據data_1如下所示:

tenant_id  tenant_class_id tenant_date
100         10001           2004-01-10
100         10001           2004-08-25
101         10001           2016-09-20
102         10002           2013-07-12
103         10003           2011-04-05
103         10004           2002-05-05
103         10003           2003-12-26

我的目標是要找到最早/第一tenant_date每個tenant_id tenant_idlong格式, tenant_datedatetime64格式

我使用以下代碼進行計算:

output = data_1.groupby(['tenant_id']).apply(lambda x: x.nsmallest(1, 'tenant_date')).reset_index(drop=1)

這對於較小的數據集來說效果很好,但是我的data_1包含約2億行。 此代碼永遠不會完成。 我有大約244 GB RAM的足夠內存。 有沒有更有效的方法來快速執行此操作?

您可以嘗試sort_values + drop_duplicates

output = data_1.sort_values(['tenant_id','tenant_date']).drop_duplicates(['tenant_id'])

sort_values + GroupBy.head

output = data_1.sort_values(['tenant_id','tenant_date']).groupby(['tenant_id']).head(1)

或者通過idxmin查看每組最小索引:

output = data_1.loc[data_1.groupby(['tenant_id'])['tenant_date'].idxmin()]

要么:

output = data_1.set_index(['tenant_class_id'])
               .groupby(['tenant_id'])['tenant_date'].nsmallest(1).reset_index()

時間

np.random.seed(123)
N = 1000000
L = pd.date_range('2015-01-01', '2018-01-01')

df = pd.DataFrame({'tenant_date': np.random.choice(L, size=N),
                   'tenant_id':np.random.randint(1000,size=N),
                   'tenant_class_id':np.random.randint(1000,size=N)})
print (df)

In [99]: %timeit data_1.sort_values(['tenant_id','tenant_date']).drop_duplicates(['tenant_id'])
1000 loops, best of 3: 1.97 ms per loop

In [100]: %timeit data_1.sort_values(['tenant_id','tenant_date']).groupby(['tenant_id']).head(1)
1000 loops, best of 3: 2.07 ms per loop

In [101]: %timeit data_1.loc[data_1.groupby(['tenant_id'])['tenant_date'].idxmin()]
100 loops, best of 3: 2.04 ms per loop

In [102]: %timeit data_1.set_index(['tenant_class_id']).groupby(['tenant_id'])['tenant_date'].nsmallest(1).reset_index()
100 loops, best of 3: 8.64 ms per loop

In [103]: %timeit data_1.groupby(['tenant_id']).apply(lambda x: x.nsmallest(1, 'tenant_date')).reset_index(drop=1)
100 loops, best of 3: 11.4 ms per loop

警告

給定組數,結果不能解決性能問題,這對於其中一些解決方案的時序會產生很大影響。

排序然后使用drop_duplicates 但是請確保首先將日期列轉換為日期時間。

df['tenant_date'] = pd.to_datetime(df['tenant_date'])
df.sort_values(['tenant_id', 'tenant_date']).drop_duplicates('tenant_id')

   tenant_id  tenant_class_id tenant_date
0        100            10001  2004-01-10
2        101            10001  2016-09-20
3        102            10002  2013-07-12
5        103            10004  2002-05-05

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM