HOWTO · Pandas

Pandas 複製 DataFrame

本教程將介紹如何使用 DataFrame.copy()方法複製 DataFrame 物件,並探討 DataFrame.copy()方法的使用。

本頁內容

若要複製 pandas DataFrame,請呼叫 DataFrame.copy()。其預設值 deep=True 會建立另一個 DataFrame,因此修改副本中的儲存格不會改變原始儲存格。需要獨立編輯資料時,請使用這個方法。

DataFrame.copy() 的語法與複製深度

這個方法接受 deep 參數:df.copy(deep=True)。預設值是 True,因此 df.copy() 與此寫法等效。使用 deep=True 時,pandas 會複製 DataFrame 的資料與索引。這是 pandas 資料結構的 deep 複製,但不會遞迴複製儲存在 object dtype 儲存格中的 Python 物件。例如,若儲存格包含可變動的清單,複製後的 DataFrame 仍可能參照同一個清單。如果工作需要巢狀物件也彼此獨立,請另外複製這些物件。

使用 deep=False 時,pandas 一開始會與來源共用底層資料與索引,而不會複製它們。之後透過任一 DataFrame 指派值時會有什麼結果,取決於 pandas 版本以及是否啟用 Copy-on-Write。淺層複製不保證修改會傳回來源,也不保證在所有設定下都能隔離修改。若需要彼此獨立,請使用預設的 deep 複製。若刻意共用資料,請確認應用程式所用 pandas 版本及 Copy-on-Write 模式的相關行為說明。

建立獨立的 DataFrame 副本

請執行以下範例:

本節中的程式碼以及顯示的標籤或輸出仍為英文。

import pandas as pd

original = pd.DataFrame({"score": [10]})
independent = original.copy()
independent.loc[0, "score"] = 99
print(f"original={original.loc[0, 'score']}, copy={independent.loc[0, 'score']}")
original=10, copy=99

這項指派會修改複製後的 DataFrame 儲存格,而 original 中的值仍是 10。範例使用預設值 deep=True;寫成 original.copy(deep=True) 則會明確指定此設定。使用 .loc[row, column] 指定要更新的儲存格;若需要比較或重複使用資料,請保留原始變數。

了解 deep=False 與共用資料

如果想建立新的 DataFrame 物件,但不立即複製其資料,淺層複製可能很有用。不過,這不代表之後的變更一定會有固定結果:pandas 的 Copy-on-Write 行為與版本會影響寫入是被隔離,還是能透過另一個物件看到。請將 deep=False 視為具有版本相依變更語義的選項,而不要把它當成同時編輯兩個 DataFrame 的可靠方法。若要確保編輯彼此獨立,請選擇 deep=True;若應用程式需要特定行為,請確認所用的 pandas 版本與 Copy-on-Write 設定。

deep 參數也不會讓巢狀物件彼此獨立。例如,若 object dtype 儲存格包含清單,複製 DataFrame 會複製 pandas 的容器,但不會遞迴複製每個清單。因此,修改儲存格中的清單,可能會影響兩個 DataFrame 都能存取的同一個物件。若這項差異會影響結果,請另外處理巢狀的可變值。

將 DataFrame 或欄位指派給變數

像 other = original 這樣的指派,會讓另一個變數綁定至同一個 DataFrame 物件。它不會呼叫 DataFrame.copy(),也不會建立獨立資料。透過任一名稱進行的修改,都會作用於同一個物件。

同樣地,scores = original["score"] 會選取欄位並取得 pandas Series;這並未明確要求建立獨立副本。若需要隔離資料,請勿以變數指派或欄位選取取代複製。DataFrame 可使用 other = original.copy(),若要取得獨立的 Series,則可使用 scores = original["score"].copy()。這樣能清楚表達意圖,也避免依賴偶然的檢視或變更行為。先選擇需要的物件:表格操作使用 DataFrame,單一欄位使用 Series;需要可獨立編輯的結果時,再呼叫 .copy()。