2013-12-18 62 views
7

我想對大熊貓數據框(數百萬行)的行進行聚合操作(總和),這是由幾個固定列(最多10列)上的條件決定的。這些列只有整數值。查詢數據幀的最快方法

我的問題是我必須做這個操作(查詢+聚合)數千次(~100 000次)。我認爲在聚合部分沒有太多優化,因爲它只是一個簡單的總和。什麼是最有效的方式來執行這項任務?有什麼方法可以在我的條件列上構建「索引」以加快每個查詢?

+4

不是說我是專家,但可以你發佈一些關於條件的代碼?你是用短路的all(),還是'and'?你可以使用算術運算來同時測試幾個條件嗎? – Roberto

+2

你應該花點時間看看實際花費的時間。 (例如在ipython中使用'%prun /%timeit'')。熊貓中的很多操作都在引擎蓋下使用''numexpr'',所以索引可以非常快。 – Jeff

+8

它們是0.13中的幾個新功能(0.13rc1不存在),您可能會覺得有用:http://pandas.pydata.org/pandas-docs/dev/enhancingperf.html#expression-evaluation-via-eval-experimental ;你也可以嘗試一個內存HDFStore! http://pytables.github.io/cookbook/inmemory_hdf5_files.html(你只需要將addl驅動參數傳遞給HDFStore,這將起作用) – Jeff

回答

1

我會嘗試在這個味道的東西:

假設你有以下的數據幀

N = 10000000 
df = pd.DataFrame({ 
    'A':np.random.binomial(1,0.5,N), 
    'B':np.random.binomial(2,0.5,N), 
    'nume1':np.random.uniform(0,1,N), 
    'nume2':np.random.normal(0,1,N)}) 

然後做這個

tmp = df[['A','B','nume1','nume2']].query('A > 0.5').groupby('B').sum().reset_index()[['B','nume1','nume2']] 

是SQL相當於

select B, sum(nume1),sum(nume2) 
from df 
where A > 0.5 
group by B 

在我的中等(i7四核,16GB內存)機器上,它需要的時間少於一秒(926ms,使用%timeit)。

我希望這會有所幫助。

1

沒有更多的細節,很難回答你的問題。

你的確應該建立一個你的條件列的索引。

df['idx'] = (df['col1'] * df['col2']) ** (df['col3'] + df['col4']) * df['col5'] == 0.012 
df = df.set_index('idx') 

將您的條件重寫爲可索引列可能很難。 請記住,您可以設置所有列的索引

df = df.set_index(['col1', 'col2', 'col3', 'col4', 'col5' ...]) 

在大熊貓的高級索引本文檔可以幫助你想想你的問題: http://pandas.pydata.org/pandas-docs/stable/indexing.html#multiindex-query-syntax