How to Fix SettingWithCopyWarning in Pandas - GeeksforGeeks

23 Dec, 2021
The SettingWithCopyWarning may occur when we are trying to modify the data in the Pandas DataFrame. This warning is thrown when we write a line of code with getting and set operations. 
To explain this in detail, Using get operation, Pandas won’t guarantee that the returned result from getting operation is either a View or Copy. If it returned a view then set operation would affect the original DataFrame. If it returned a copy then it would modify the copy but the original DataFrame remains unchanged. So here we are not sure whether changes happened to DataFrame or not.
DataFrame
Student Name
Percentage
Grade
Akhil
–
–
Sai
65
C
Rohit
90
O
Prasanth
79
B
Divya
89
A
Python3
# import necessary packagesimport pandas as pd # create a dataframemarks = pd.DataFrame({'Name': ['Akhil', 'Sai', 'Rohit', 'Prasanth', 'Divya'],                      'Percentage': ['-', 65, 90, 79, 89],                      'Grade': ['-', 'C', 'O', 'B', 'A']}) # Assign Absent if percentage is not specifiedmarks[marks.Percentage == '-'].Grade = 'Ab'
Output
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
To solve this problem instead of slicing while getting the required data use the loc method to get required rows and columns. And also use the copy method to store a copy of DataFrame in another variable such that we can separate the get and set operation into 2 lines.
Use the above DataFrame and loc method while getting the required rows & columns in getting an operation.
Python3
# import necessary packagesimport pandas as pd # create a dataframemarks = pd.DataFrame({'Name': ['Akhil', 'Sai', 'Rohit', 'Prasanth', 'Divya'],                      'Percentage': ['-', 65, 90, 79, 89],                      'Grade': ['-', 'C', 'O', 'B', 'A']}) # Assign Absent if percentage is not specifiedmarks.loc[marks.Percentage == '-', 'Grade'] = 'Ab' # modified contentmarks
Output
Explanation- Instead of slicing which is throwing warning, Here we used the loc method.
Note: But this loc method doesn’t ensure a 100% guarantee on warning-free output. So it is advised to create a copy of the original Data Frame and make modifications to that.
Create a copy of a DataFrame and make changes to it by using loc & copy methods.
Python3
# import necessary packagesimport pandas as pd # create a dataframemarks = 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 contentAbsent_Students
Explanation- The above Absent_Students is a copy of the original DataFrame with only Absent students. It ensures that we are changing modifications only on the copy of a DataFrame. So it removes confusion between view & copy.
sweetyty
Picked
Python How-to-fix
Python-pandas
Python
Writing code in comment?
Please use ide.geeksforgeeks.org,
generate link and share the link here.
How to Install PIP on Windows ?
How to drop one or multiple columns in Pandas Dataframe
How To Convert Python Dictionary To JSON?
Selecting rows in pandas DataFrame based on conditions
Check if element exists in list in Python
Defaultdict in Python
Python | Get unique values from a list
Python | os.path.join() method
Create a directory in Python
Python | Pandas dataframe.groupby()