📌  相关文章
📜  SettingWithCopyWarning:试图在 DataFrame 中的切片副本上设置值.尝试改用 .loc[row_indexer,col_indexer] = value - Python (1)

📅  最后修改于: 2023-12-03 15:05:11.575000             🧑  作者: Mango

SettingWithCopyWarning

当一个DataFrame被切片操作后,再进行值的修改时,有时候会出现一个警告"SettingWithCopyWarning"。这个警告提示开发者要么修改副本,要么修改原数据。这个警告发生的原因是因为切片操作会创建一个新的副本,如果是对这个副本修改并且不返回,那么对原数据的操作是不确定的。

解决方法
  1. 使用.loc[row_indexer, col_indexer] = value方法,显式地使用.loc修改原数据,而不是对一个副本进行操作,这能够实现对原数据的修改。
df.loc[row_indexer, col_indexer] = value
  1. 使用.copy()创造一个数据副本,这种情况下会创建一个原始数据的完全的、互相独立的副本,并且对此副本的修改不会影响原始数据。
df_copy = df.copy()
例子

下面是一个例子,首先我们展示了创建一个DataFrame,将其切片并尝试进行更改,此时会出现"SettingWithCopyWarning"警告。然后我们使用.loc[row_indexer, col_indexer] = value显式地修改原数据,并且将其输出。

import pandas as pd
import numpy as np

df = pd.DataFrame(np.random.randn(5, 3), columns=['A', 'B', 'C'])
print(df)

sliced_df = df.iloc[1:4]
sliced_df['A'] = 0

print(df)

输出结果:

          A         B         C
0 -0.158872 -1.942848  0.122513
1 -0.045605  0.444266  1.739403
2 -0.319895 -0.973439 -1.583657
3 -0.781735 -1.457004  0.360295
4 -0.324276  1.318361 -1.086415

D:\anaconda3\lib\site-packages\pandas\core\indexing.py:670: SettingWithCopyWarning: 
A value is trying to be set on a copy of a slice from a DataFrame
Try using .loc[row_indexer,col_indexer] = value instead

See the caveats in the documentation: https://pandas.pydata.org/pandas-docs/stable/user_guide/indexing.html#returning-a-view-versus-a-copy
  iloc._setitem_with_indexer(indexer, value)

          A         B         C
0 -0.158872 -1.942848  0.122513
1  0.000000  0.444266  1.739403
2  0.000000 -0.973439 -1.583657
3  0.000000 -1.457004  0.360295
4 -0.324276  1.318361 -1.086415