我無法確定這一點:我有一個函式可以從 S3 存盤桶中讀取一堆 csv 檔案,將它們連接起來并回傳 DataFrame:
def create_df():
df1 = pd.read_csv(s3_path 'file_1.csv')
df2 = pd.read_csv(s3_path 'file_2.csv')
return pd.concat([df1, df2], ignore_index=True)
我的第二個函式執行聚合:
def aggregate_values(df):
columns = ['col_c', 'col_d']
new_df = df.groupby(columns, as_index=False) \
.agg({'col_a': 'sum', 'col_b': 'mean'})
return new_df
由于記憶體不足錯誤,函式 aggregate_values 失敗。
df = create_df()
# OOM error !!!
new_df = aggregate_values(df)
奇怪的是,如果我將 DataFrame 寫入本地檔案系統,然后再將其讀回,聚合在新 DataFrame 上不會出現故障。
df = create_df()
df.to_csv('path_to_store/f.csv', index=False)
df2 = pd.read_csv('path_to_store/f.csv')
# works fine!!!
new_df = aggregate_values(df2)
我的猜測是 create_df() 回傳的 DataFrame 有問題。通過將其寫出來并在 Pandas 中讀回,以某種方式糾正了問題。但我想確切地找出 DataFrame 出了什么問題。
我該如何除錯這個問題?
已編輯
我在運行代碼的機器上有 32G RAM。DataFrame 有大約 200 萬條記錄,占用大約 0.5G 的存盤和記憶體空間。
uj5u.com熱心網友回復:
您沒有評論您的記憶體大小,也沒有評論 .CSV 或資料框的大小。但我可以冒險一些猜測。我有幾點意見:
- 連接后,您有機會核對 df1 和 df2。只需分配
None給他們,以回收一些 RAM。 - .groupby() 可能接受密集的 numpy 陣列并產生更高開銷的稀疏陣列。你可能想調查一下。
- 計算平均值可能會變成例如
int8,float64這顯然會消耗更多空間。 - 這是最大的專案: .groupby() 可能回傳一個(可變)視圖,而不是一個全新的 numpy 陣列。到檔案系統的往返解決了這個問題,但是一個簡單的 .copy() 會產生相同的效果,所以試試吧。
請在此處發布答案,讓我們知道情況如何。
uj5u.com熱心網友回復:
我發現了問題,結果證明是一個好問題。
create_df() 回傳的 DataFrame 中的一列具有 dtype 類別。不知道這是怎么發生的,因為它應該是字串。此列在 grouper 中用于聚合。通過將 DataFrame 寫入本地檔案系統然后將其讀回,Pandas 將該列正確地重新解釋為字串。
使用正確的資料型別,聚合可以快速運行并回傳,并且不會出現任何記憶體問題。我不明白為什么對分類列進行分組會導致 OOM 錯誤——這是另一天的話題。
轉載請註明出處,本文鏈接:https://www.uj5u.com/qianduan/463141.html
上一篇:物體框架核心關系問題
