我在Ubuntu 16.10上使用numpy(1.13.1)和pandas(0.20.3),使用python 2.7或3.5(兩者都有相同的問題)。熊貓使用大量更多的內存用於存儲比要求
我正在研究熊貓記憶處理(特別是當它複製或不復制數據)並遇到了我不明白的重大記憶問題。雖然我已經看到(很多)人們關於其內存性能的其他問題,但我還沒有發現任何直接解決此問題的方法。
具體而言,熊貓分配lot更多的內存比我問它。我注意到,當只是想分配一個數據幀具有特定大小的列了一些非常奇怪的現象:
import pandas as pd, numpy as np
GB = 1024**3
df = pd.DataFrame()
df['MyCol'] = np.ones(int(1*GB/8), dtype='float64')
當我執行此我看到我的蟒蛇過程實際上分配6GB內存,(12G如果我問了2GB ,如果我要求3GB,則爲21GB,如果我要求4GB,則計算機會中斷: - /),而不是預期的1GB。我首先想到的可能是Python正在進行一些積極的預分配,但是如果我只是自己構建numpy數組,我會得到我每次要求的內存量,無論是1GB,10GB,25GB,無論如何。
此外,什麼是更有趣的是,如果我稍微改變代碼如下:
df['MyCol'] = np.ones(int(1*GB), dtype='uint8')
它分配這麼多的內存崩潰我的系統(單獨運行numpy的呼叫正確地分配1GB內存)。 (編輯2017/8/17:出於好奇,我今天嘗試使用更新版本的熊貓(0.20.3)和numpy(1.13.1),並將RAM升級到64GB,並且運行此命令仍然失敗,分配所有64(ISH)GB可用RAM的。)
我能理解加倍,甚至三倍問,如果大熊貓進行復印,也許是內存的分配另一列存儲索引,但我不能解釋它實際上在做什麼。粗略瀏覽代碼也不完全清楚。
我試着以幾種不同的方式構建數據框,所有的結果都一樣。鑑於其他人成功地使用這個軟件包進行大數據分析,我必須假定我正在做一些可怕的錯誤,儘管從我能告訴給出的文檔應該是正確的。
想法?
一些附加註釋:
- 即使當存儲器使用率大,熊貓仍然(錯誤地),如果我分配一個1GB陣列它報告1GB報告時memory_usage()被調用所期望的數據大小(即,即使實際分配了6-10GB)。
- 在所有情況下,索引都很小(由memory_usage()報告,這可能不準確)。
- 取消分配大熊貓DataFrame(df = None,gc.collect())實際上並不釋放所有內存。使用這種方法必定會有泄漏。
嘗試此代替:'DF = pd.DataFrame({ 'MyCol':np.ones(INT(1 * GB), dtype = np.uint8)})' – MaxU
@MaxU雖然這樣表現更好,但它仍然不夠完美。有一個很大的開銷(對象的大小的100%,多一點),得到分配(我認爲這是製作一份數據的副本)。這似乎有比我的例子中更多似是而非的解釋,但如果我不幸地需要拋出超過15GB的內存,這並沒有幫助。 (注意:即使數據被分割到多個通道上,也會發生這種情況,例如,3個5GB通道需要使用此方法分配近30GB的數據,因此如果正在創建數據副本,則不會將其釋放,直到最後纔會釋放它們。) – Anthony
df.index佔用了多少空間?如果添加另一列,可能是相同的'np.array',內存如何使用更改? – hpaulj