pandas警告:SettingWithCopyWarning


  在使用pandas對DataFrame進行賦值操作時,會出現一個看似莫名巧妙的告警信息:

  SettingWithCopyWarning:A value is trying to be set on a copy of slice from a DataFrame

  Try using .loc[row_indexer,col_indexer] = value instead

  這條告警信息的大意是,“嘗試在DataFrame一個切片的副本上進行賦值,使用 .loc[row_indexer,col_indexer] = value 代替當前賦值操作”。導致這條告警產生的原因,是由於pandas無法判斷對原始DataFrame進行切片,產生的是視圖還是副本。如果切片產生的是視圖,則賦值操作會修改原始DataFrame,如果產生的是副本,則不會修改原始的DataFrame。

  一般產生這條告警,都是由於使用鏈式索引(chained indexing)賦值導致的;而使用  .loc[row_indexer,col_indexer] 則會產生一個新的DataFrame,在某些情況下,可以解決該告警問題(ps:導致 SettingWithCopyWarning 告警產生的情況不止一種!)。如果你選擇忽視這條告警,那么你最好查看一下自己的賦值操作有沒有成功(雖然本人實際運用中查看了多次,都是成功的,但不代表每一次都能成功,所以建議還是不要忽視這條告警)。

 

# 下面的操作就會出現SettingWithCopyWarning警告
df_select = df[df['col_name]>value]   # 通過條件篩選,得到df_select
# 假設此時我們想修改df_select列 'col'的值:
df_select['col']  = new_value
# 此時就會出現SettingWithCopyWarning,因為df_select 發生改變,pandas無法判斷原始df究竟會不會改變
# 實際上上述過程就用了鏈式索引進行賦值,上述過程等價於:
 df[df['col_name]>value]['col']  = new_value
# 解決這個問題比較好的一個方法是手動進行復制:
df_select = df[df['col_name]>value].copy()  # 這樣df_select是df的一個復本,df_select的改變也不會影響df

  

  總而言之,應該竟可能的避免使用鏈式索引對 DataFrame 進行賦值操作。更多產生告警的原因及解決方法的詳解,可以參考pandas官方文檔中的 "Indexing and Selecting Data"模塊下的"Returning a view versus a copy"  http://pandas.pydata.org/pandas-docs/stable/indexing.html#returning-a-view-versus-a-copy。也可參考我看到一篇寫的很好的文章:https://www.dataquest.io/blog/settingwithcopywarning/(英文原文),https://www.jianshu.com/p/72274ccb647a(中文翻譯版)。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM