Python Pandas 中的視圖(View)與副本(Copy) : 避免資料操作錯誤的指南; 如何處理SettingWithCopyWarning ?

加入好友
加入社群
Python Pandas 中的視圖(View)與副本(Copy) : 避免資料操作錯誤的指南; 如何處理SettingWithCopyWarning ? - 儲蓄保險王

在使用 Pandas 處理資料時,視圖與副本的概念至關重要。
理解它們的行為可以幫助您避免觸發警告或進行意外的資料修改。


核心概念

視圖 (View)

當您選取 DataFrame 的某部分資料時(例如 df[['A', 'B']]),
創建的通常是一個視圖。
視圖與原始 DataFrame 共享底層資料
但直接修改視圖的資料可能不會真正影響原始 DataFrame,
並且會觸發 SettingWithCopyWarning

示例

df_view = df_original[['A', 'B']]  # 未使用 .copy()
df_view.loc[0, 'A'] = 999  # 嘗試修改視圖

輸出結果:

Python Pandas 中的視圖(View)與副本(Copy) : 避免資料操作錯誤的指南; 如何處理SettingWithCopyWarning ? - 儲蓄保險王

觸發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  # 嘗試修改視圖

視圖的行為特點

  1. 修改視圖時,可能會觸發 SettingWithCopyWarning,提醒用戶這是基於切片的操作。
  2. 實際上不會影響原始 DataFrame,這與 NumPy 中的視圖行為不同。
Python Pandas 中的視圖(View)與副本(Copy) : 避免資料操作錯誤的指南; 如何處理SettingWithCopyWarning ? - 儲蓄保險王

修改視圖後,df_original 沒有改變


副本 (Copy)

使用 .copy() 創建的副本擁有自己獨立的資料存儲空間。對副本的修改完全不會影響原始 DataFrame。

示例

df_copy = df_original[['A', 'B']].copy()
df_copy.loc[0, 'A'] = 888  # 修改副本

輸出結果:

Python Pandas 中的視圖(View)與副本(Copy) : 避免資料操作錯誤的指南; 如何處理SettingWithCopyWarning ? - 儲蓄保險王

不影響df_original,也不會觸發warning

副本的行為特點

  1. 修改副本不會影響原始 DataFrame。
  2. 不會觸發警告,操作更安全。

修改視圖與副本的影響

以下是完整的測試代碼與輸出結果:

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)  # 原始資料仍未受到影響

輸出結果:

Python Pandas 中的視圖(View)與副本(Copy) : 避免資料操作錯誤的指南; 如何處理SettingWithCopyWarning ? - 儲蓄保險王

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']])進行賦值時。

解決方法

  1. 明確創建副本
    使用 .copy() 明確告訴 Pandas,您希望創建一個副本:
df_copy = df_original[['A', 'B']].copy()

使用 .loc.iloc 進行操作
避免鏈式索引,改用 .loc.iloc

df.loc[df['A'] > 0, 'B'] = value

總結

  1. 視圖 (View) 是原始 DataFrame 的一個「窗口」,修改時可能觸發警告,但實際上不會影響原始資料。
  2. 副本 (Copy) 是安全的獨立資料副本,推薦在需要修改資料時使用。
  3. 最佳實踐
    • 使用 .copy() 明確創建副本。
    • 使用 .loc.iloc 進行賦值操作,避免鏈式索引。

推薦hahow線上學習python: https://igrape.net/30afN

加入好友
加入社群
Python Pandas 中的視圖(View)與副本(Copy) : 避免資料操作錯誤的指南; 如何處理SettingWithCopyWarning ? - 儲蓄保險王

儲蓄保險王

儲蓄險是板主最喜愛的儲蓄工具,最喜愛的投資理財工具則是ETF,最喜愛的省錢工具則是信用卡

You may also like...

發佈留言

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *