我有一個 600MB 的 CSV,我使用read_csv以下兩種方法之一用 pandas 加載它。
def read_my_csv1():
df = pd.read_csv('my_data.csv')
print(len(df))
def read_my_csv2():
with open('my_data.csv') as f:
file_contents = f.read()
data_frame = pd.read_csv(io.StringIO(file_contents))
print(len(data_frame))
第一種方法給出的峰值記憶體使用量為 1GB。
第二種方法給出了 4GB 的峰值記憶體使用量。
我用 來測量峰值記憶體使用量fil-profile。
差距怎么會這么大?有沒有辦法從不會使峰值記憶體使用量飆升的字串中加載 CSV?
uj5u.com熱心網友回復:
差距怎么會這么大?
StringIO使用Py_UCS4 [source]型別的緩沖區。那是 32 位資料型別,而 CSV 檔案可能是 ASCII 或 UTF-8。所以我們這里的開銷是 3 倍,額外占了大約 1.8 GB。此外,StringIO緩沖區可能會過度分配 12.5% [來源]。
最佳案例:
file_contents 600 MB
io.StringIO 2400 MB
data_frame 600 MB (at least)
DLLs, EXEs, ... ? MB
-----------------------
3600 MB (at least)
超額分配 12.5% 的情況:
file_contents 600 MB
io.StringIO 2700 MB
data_frame 600 MB (at least)
DLLs, EXEs, ... ? MB
-----------------------
3900 MB (at least)
有沒有辦法從不會使峰值記憶體使用量飆升的字串中加載 CSV?
del臨時物件- 不要使用 StringIO。
uj5u.com熱心網友回復:
它看起來像StringIO維護自己的字串資料副本,因此至少暫時您在記憶體中擁有三個資料副本 - 一個在 中file_contents,一個在StringIO物件中,一個在最終資料幀中。同時,至少理論上可以read_csv逐行讀取輸入檔案,從而在直接從檔案中讀取時,最終資料幀中只有一份完整資料的副本。
您可以在創建物件后嘗試deleting ,看看是否可以改善情況。file_contentsStringIO
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/464541.html
上一篇:如何讀取csv中列的每個單元格并將每個單元格作為bash中jq的輸入
下一篇:帶有標題的Kotlin格式CSV
