python – SettingWithCopyWarning even when using .loc[row_indexer,col_indexer] = value

python – SettingWithCopyWarning even when using .loc[row_indexer,col_indexer] = value

If you use .loc[row,column] and still get the same error, its probably because of copying another data frame. You have to use .copy().

This is a step by step error reproduction:

import pandas as pd

d = {col1: [1, 2, 3, 4], col2: [3, 4, 5, 6]}
df = pd.DataFrame(data=d)
df
#   col1    col2
#0  1   3
#1  2   4
#2  3   5
#3  4   6

Creating a new column and updating its value:

df[new_column] = None
df.loc[0, new_column] = 100
df
#   col1    col2    new_column
#0  1   3   100
#1  2   4   None
#2  3   5   None
#3  4   6   None

No error I receive. However, lets create another data frame given the previous one:

new_df = df.loc[df.col1>2]
new_df
#col1   col2    new_column
#2  3   5   None
#3  4   6   None

Now, using .loc, I will try to replace some values in the same manner:

new_df.loc[2, new_column] = 100

However, I got this hateful warning again:

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

SOLUTION

use .copy() while creating the new data frame will solve the warning:

new_df_copy = df.loc[df.col1>2].copy()
new_df_copy.loc[2, new_column] = 100

Now, you wont receive any warnings!

If your data frame is created using a filter on top of another data frame, always use .copy().

Have you tried setting directly?:

value1.loc[value1[Total Population] == *, Total Population] = 4

python – SettingWithCopyWarning even when using .loc[row_indexer,col_indexer] = value

I came here because I wanted to conditionally set the value of a new column based on the value in another column.

What worked for me was numpy.where:

import numpy as np
import pandas as pd
...

df[Size] = np.where((df.value > 10), Greater than 10, df.value)

From numpy docs, this is equivelant to:

[xv if c else yv
 for c, xv, yv in zip(condition, x, y)]

Which is a pretty nice use of zip…

Leave a Reply

Your email address will not be published.