2016-07-29 36 views
2

我想迭代地添加一些從一組csv文件中讀取的熊貓數據框,並且在第16個文件後出現內存錯誤。新文件是大約30萬行的熊貓。以高效的內存方式迭代地添加熊貓數據框

有沒有辦法在硬盤驅動器(例如使用hdf5)或以更高效的內存方式執行此操作?

查看下面的代碼。請注意,sum_of_all_files從一個空的數據框開始。

sum_of_all_files = pd.DataFrame() 
for file_name in list_of_files: 
    file_df=pd.read_csv(file_name,index_col=0,header=None).dropna() 
    sum_of_all_files=sum_of_all_files.add(file_df,fill_value=0, axis='index') 

謝謝!

編輯:我想通過索引添加,即如果兩行有相同的索引,添加它們。我通過在最後一行添加「axis ='index'」來修正上面的代碼。

+1

您的目標是將所有內容加載到一個DF中,或者將其一次性處理並寫回磁盤? – MaxU

+0

@MaxU目標是創建一個表格,其中包含按鍵添加的所有csv文件的內容。它可以在磁盤或內存中... – Escachator

+1

有多少列有csvs? – jezrael

回答

1

您可以使用concatsum

files = glob.glob('files/*.csv') 

dfs = [pd.read_csv(file_name,index_col=0,header=None).dropna() for file_name in files] 
df = pd.concat(dfs).sum() 
print (df) 
+0

謝謝。嘗試它,會報告。爲什麼這會更「記憶效率」? – Escachator

+1

好問題,我不是100%確定它是否會提高內存效率,因爲如果使用大型文件,可能會產生問題。但最好的測試它。 – jezrael

+0

我認爲concat和sum將不起作用,因爲我想爲dfs的每個元素總結具有相同索引的行。我想我們需要轉換問題來總結重複索引,一旦concat完成... – Escachator

1

UPDATE:我只想補充閱讀數據塊的所有的CSV到您的解決方案。我想你已經在做了非常出色的內存節省方面...

sum_of_all_files = pd.DataFrame() 
for file_name in list_of_files: 
    for file_df in pd.read_csv(file_name, index_col=0, header=None, chunksize=10**5) 
     sum_of_all_files = sum_of_all_files.add(file_df.dropna(), fill_value=0, axis='index') 

OLD答案:

理念:我們會首先讀取文件到total DF,然後我們會閱讀一個文件在每個迭代步驟,從第二個文件在你list_of_files開始和動態添加它到total DF

PS你可以更進一步,以塊的形式讀取每個CSV文件,如果存在着巨大的網絡連接不適合內存的文件:

total = pd.read_csv(list_of_files[0], index_col=0, header=None).dropna() 

for f in list_of_files[1:]: 
    for chunk in pd.read_csv(f,index_col=0,header=None, chunksize=10**5): 
     total = total.add(chunk.dropna(), fill_value=0, axis='index') 
+0

謝謝!將嘗試。如果我不使用dropna,行數將「爆炸」,如每個文件中有數百萬個空行。數據不對齊,我需要通過索引來添加它們。我相信我的代碼中有另一個錯誤... – Escachator

+1

@Escachator,當然,試試看 – MaxU