如何修复 Pandas 中的 SettingWithCopyWarning
SettingWithCopyWarning可能 当我们尝试修改Pandas DataFrame中的数据时发生。当我们编写一行带有获取和设置操作的代码时会引发此警告。
为了详细解释这一点,使用 get 操作, Pandas 不保证 get 操作返回的结果是 View 或 Copy。如果它返回一个视图,那么设置操作将影响原始 DataFrame。如果它返回一个副本,那么它将修改副本,但原始 DataFrame 保持不变。所以在这里我们不确定DataFrame是否发生了变化。
数据框 Student Name Percentage Grade Akhil – – Sai 65 C Rohit 90 O Prasanth 79 B Divya 89 A
引发警告的代码
Python3
# import necessary packages
import pandas as pd
# create a dataframe
marks = pd.DataFrame({'Name': ['Akhil', 'Sai', 'Rohit', 'Prasanth', 'Divya'],
'Percentage': ['-', 65, 90, 79, 89],
'Grade': ['-', 'C', 'O', 'B', 'A']})
# Assign Absent if percentage is not specified
marks[marks.Percentage == '-'].Grade = 'Ab'
Python3
# import necessary packages
import pandas as pd
# create a dataframe
marks = pd.DataFrame({'Name': ['Akhil', 'Sai', 'Rohit', 'Prasanth', 'Divya'],
'Percentage': ['-', 65, 90, 79, 89],
'Grade': ['-', 'C', 'O', 'B', 'A']})
# Assign Absent if percentage is not specified
marks.loc[marks.Percentage == '-', 'Grade'] = 'Ab'
# modified content
marks
Python3
# import necessary packages
import pandas as pd
# create a dataframe
marks = pd.DataFrame({'Name': ['Akhil', 'Sai', 'Rohit', 'Prasanth', 'Divya'],
'Percentage': ['-', '-', 90, 79, 89],
'Grade': ['-', '-', 'O', 'B', 'A']})
# create a copy of original DataFrame whose
$ percentage is empty(absenties)
Absent_Students = marks.loc[marks.Percentage == '-', :].copy()
# Make their grade as 'Ab' which indicates absent.
Absent_Students.Grade = 'Ab'
# modified content
Absent_Students
输出
C:\ProgramData\Anaconda3\lib\site-packages\pandas\core\generic.py:5303: 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
self[name] = value
解决方案
为了解决这个问题,而不是在获取所需数据时进行切片,请使用loc方法来获取所需的行和列。并且还使用 copy 方法将 DataFrame 的副本存储在另一个变量中,这样我们就可以将 get 和 set 操作分成 2 行。
示例 1:
在获取操作所需的行和列时使用上述 DataFrame和 loc 方法。
Python3
# import necessary packages
import pandas as pd
# create a dataframe
marks = pd.DataFrame({'Name': ['Akhil', 'Sai', 'Rohit', 'Prasanth', 'Divya'],
'Percentage': ['-', 65, 90, 79, 89],
'Grade': ['-', 'C', 'O', 'B', 'A']})
# Assign Absent if percentage is not specified
marks.loc[marks.Percentage == '-', 'Grade'] = 'Ab'
# modified content
marks
输出
说明- 不是切片,而是抛出警告,这里我们使用了 loc 方法。
注意:但是这种 loc 方法并不能确保 100% 保证无警告输出。因此,建议创建原始数据框的副本并对其进行修改。
示例 2:
创建 DataFrame 的副本并使用 loc 和 copy 方法对其进行更改。
Python3
# import necessary packages
import pandas as pd
# create a dataframe
marks = pd.DataFrame({'Name': ['Akhil', 'Sai', 'Rohit', 'Prasanth', 'Divya'],
'Percentage': ['-', '-', 90, 79, 89],
'Grade': ['-', '-', 'O', 'B', 'A']})
# create a copy of original DataFrame whose
$ percentage is empty(absenties)
Absent_Students = marks.loc[marks.Percentage == '-', :].copy()
# Make their grade as 'Ab' which indicates absent.
Absent_Students.Grade = 'Ab'
# modified content
Absent_Students
输出
说明- 上面的 Absent_Students 是原始 DataFrame 的副本,只有 Absent 学生。它确保我们仅在 DataFrame 的副本上更改修改。所以它消除了视图和复制之间的混淆。