2016-10-03 458 views
0

我有兩隻大熊貓DataFrames df1df2用相當標準的格式:大熊貓上的外部合併DataFrames導致MemoryError ---如何將「大數據」與大熊貓合併?

one two three feature 
A 1 2  3 feature1 
B 4 5  6 feature2 
C 7 8  9 feature3 
D 10 11  12 feature4 
E 13 14  15 feature5 
F 16 17  18 feature6 
... 

併爲df2相同的格式。這些數據幀的大小大約爲175MB和140MB。

merged_df = pd.merge(df1, df2, on='feature', how='outer', suffixes=('','_features')) 

我得到以下的MemoryError:

File "/nfs/sw/python/python-3.5.1/lib/python3.5/site-packages/pandas/tools/merge.py", line 39, in merge 
    return op.get_result() 
File "/nfs/sw/python/python-3.5.1/lib/python3.5/site-packages/pandas/tools/merge.py", line 217, in get_result 
    join_index, left_indexer, right_indexer = self._get_join_info() 
File "/nfs/sw/python/python-3.5.1/lib/python3.5/site-packages/pandas/tools/merge.py", line 353, in _get_join_info 
    sort=self.sort, how=self.how) 
File "/nfs/sw/python/python-3.5.1/lib/python3.5/site-packages/pandas/tools/merge.py", line 559, in _get_join_indexers 
    return join_func(lkey, rkey, count, **kwargs) 
File "pandas/src/join.pyx", line 187, in pandas.algos.full_outer_join (pandas/algos.c:61680) 
    File "pandas/src/join.pyx", line 196, in pandas.algos._get_result_indexer (pandas/algos.c:61978) 
MemoryError 

是否有可能有一個 「大小限制」 大熊貓dataframes合併是什麼時候?我很驚訝,這是行不通的。也許這是某個熊貓版本的錯誤?

編輯:正如在評論中提到的,合併列中的許多重複項可能很容易導致RAM問題。參見:Python Pandas Merge Causing Memory Overflow

現在的問題是,我們該如何做到這一點合併?不知何故,最好的辦法是分割數據框。

+0

在'feature'列中是否有重複內容?如果有很多重複項,你的連接最終會變成**非常大** – maxymoo

+0

@maxymoo是的。你能解釋爲什麼這會超過內存限制嗎?假設'df1'有1000萬行,特徵1有500K行,特徵2有500K行等等。數據幀本身只有150 MB ---爲什麼會出現內存錯誤? – ShanZhengYang

+0

你使用的是32位的python/64位? –

回答

1

您可以嘗試第一個過濾器df1通過unique值,merge和最後concat輸出。

如果只需要外連接,我覺得還有內存問題。但是,如果爲每個循環的過濾器輸出添加一些其他代碼,它可以工作。

dfs = [] 
for val in df.feature.unique(): 
    df1 = pd.merge(df[df.feature==val], df2, on='feature', how='outer', suffixes=('','_key')) 
    #http://stackoverflow.com/a/39786538/2901002 
    #df1 = df1[(df1.start <= df1.start_key) & (df1.end <= df1.end_key)] 
    print (df1) 
    dfs.append(df1) 

df = pd.concat(dfs, ignore_index=True) 
print (df) 

其他的解決方案是使用dask.dataframe.DataFrame.merge

1

嘗試指定一個數據類型的數字列,以減少現有的數據幀的大小,如:

df[['one','two', 'three']] = df[['one','two', 'three']].astype(np.int32) 

這應該顯著減少內存,並希望讓你瓶坯合併。

+0

我猜這可能對於非常大的連接沒有太大幫助,如上所述。有沒有一種有效的方法來通過獨特的「特徵」來分割數據框?如果有(比方說)具有100 MB數據幀的10個功能,您可能會獲得更小的數據幀(如果統一,每個大約10 MB) – ShanZhengYang

+0

我不確定是否有效地按照您的方式拆分數據幀暗示,但它可能會刪除在兩個初始數據框之間共享的所有列。目標是外連接,因此移除對數據框不唯一的列不會影響結果,但會減少內存。就像@jezrael剛剛發佈的答案一樣。 –