在使用 Pandas 處理資料時,視圖與副本的概念至關重要。
理解它們的行為可以幫助您避免觸發警告或進行意外的資料修改。
核心概念
視圖 (View)
當您選取 DataFrame 的某部分資料時(例如 df[['A', 'B']]
),
創建的通常是一個視圖。
視圖與原始 DataFrame 共享底層資料,
但直接修改視圖的資料可能不會真正影響原始 DataFrame,
並且會觸發 SettingWithCopyWarning
。
示例:
df_view = df_original[['A', 'B']] # 未使用 .copy()
df_view.loc[0, 'A'] = 999 # 嘗試修改視圖
輸出結果:

觸發SettingWithCopyWarning:
<ipython-input-21-5e213e13ee7f>:2: SettingWithCopyWarning:
A value is trying to be set on a copy of a slice from a DataFrame
See the caveats in the documentation: https://pandas.pydata.org/pandas-docs/stable/user_guide/indexing.html#returning-a-view-versus-a-copy
df_view.loc[0, 'A'] = 999 # 嘗試修改視圖
視圖的行為特點:
- 修改視圖時,可能會觸發
SettingWithCopyWarning
,提醒用戶這是基於切片的操作。 - 實際上不會影響原始 DataFrame,這與 NumPy 中的視圖行為不同。

修改視圖後,df_original 沒有改變
副本 (Copy)
使用 .copy()
創建的副本擁有自己獨立的資料存儲空間。對副本的修改完全不會影響原始 DataFrame。
示例:
df_copy = df_original[['A', 'B']].copy()
df_copy.loc[0, 'A'] = 888 # 修改副本
輸出結果:

不影響df_original,也不會觸發warning
副本的行為特點:
- 修改副本不會影響原始 DataFrame。
- 不會觸發警告,操作更安全。
修改視圖與副本的影響
以下是完整的測試代碼與輸出結果:
import pandas as pd
# 建立原始 DataFrame
df_original = pd.DataFrame({
'A': [1, 2, 3, 4],
'B': [10, 20, 30, 40],
'C': [100, 200, 300, 400]
})
# 創建視圖和副本
df_view = df_original[['A', 'B']] # 創建視圖
df_copy = df_original[['A', 'B']].copy() # 創建副本
# 修改視圖
df_view.loc[0, 'A'] = 999
print("原始 DataFrame (視圖修改後):")
print(df_original) # 原始資料未受到影響
# 修改副本
df_copy.loc[0, 'A'] = 888
print("\n原始 DataFrame (副本修改後):")
print(df_original) # 原始資料仍未受到影響
輸出結果:

SettingWithCopyWarning
警告:
<ipython-input-25-25278166cae5>:15: SettingWithCopyWarning:
A value is trying to be set on a copy of a slice from a DataFrame
See the caveats in the documentation: https://pandas.pydata.org/pandas-docs/stable/user_guide/indexing.html#returning-a-view-versus-a-copy
df_view.loc[0, 'A'] = 999
為什麼觸發 SettingWithCopyWarning
?
SettingWithCopyWarning
是 Pandas 的一種提醒,告訴用戶當前操作的對象可能是視圖而非副本,從而避免不確定的行為。這種警告通常發生在切片操作後(如 df[['A', 'B']]
)進行賦值時。
解決方法
- 明確創建副本:
使用.copy()
明確告訴 Pandas,您希望創建一個副本:
df_copy = df_original[['A', 'B']].copy()
使用 .loc
或 .iloc
進行操作:
避免鏈式索引,改用 .loc
或 .iloc
:
df.loc[df['A'] > 0, 'B'] = value
總結
- 視圖 (View) 是原始 DataFrame 的一個「窗口」,修改時可能觸發警告,但實際上不會影響原始資料。
- 副本 (Copy) 是安全的獨立資料副本,推薦在需要修改資料時使用。
- 最佳實踐:
- 使用
.copy()
明確創建副本。 - 使用
.loc
或.iloc
進行賦值操作,避免鏈式索引。
- 使用
推薦hahow線上學習python: https://igrape.net/30afN
近期留言