Skip to content
Advertisement

SettingWithCopyWarning, how to stop it?

I have this code, it’s working for the first 9 itterations and then I get the SettingWithCopyWarning and it doesnt continue on, what can I do?

df_day = df.copy()
date = df_day['Date']
df_day['Day'] = 'N/A'
x = 0
for str in df_day:
    df_day['Day'][x] = datetime.datetime.strptime(date[x], '%d/%m/%Y').weekday()
    x = x + 1
y = 0

for int in df_day['Day']:
    if df_day['Day'][y] == 0:
        df_day['Day'][y] = 'Monday'
        y = y + 1
    elif df_day['Day'][y] == 1:
        df_day['Day'][y] = 'Tuesday'
        y = y + 1
    elif df_day['Day'][y] == 2:
        df_day['Day'][y] = 'Wednesday'
        y = y + 1
    elif df_day['Day'][y] == 3:
        df_day['Day'][y] = 'Thursday'
        y = y + 1
    elif df_day['Day'][y] == 4:
        df_day['Day'][y] = 'Friday'
        y = y + 1
    elif df_day['Day'][y] == 5:
        df_day['Day'][y] = 'Saturday'
        y = y + 1
    elif df_day['Day'][y] == 6:
        df_day['Day'][y] = 'Sunday'
        y = y + 1
df_day.head(15)

So I have this now, but it still only runs through the first 10 lines of data! Something to do with the first for loop I think! (I know it’s still a for loop but its been requested as being in a for loop!)

x = 0
for int in df_day:
    if x < length_data_day:
        df_day.loc[x,'Day'] = datetime.datetime.strptime(date[x], '%d/%m/%Y').weekday()
        x = x + 1
    elif x == length_data_day:
        end
df_day.head(15)
y = 0
for int in df_day['Day']:
    if df_day.loc[y,'Day'] == 0:
        df_day.loc[y,'Day'] = 'Monday'
        y = y + 1
    elif df_day.loc[y,'Day'] == 1:
        df_day.loc[y,'Day'] = 'Tuesday'
        y = y + 1
    elif df_day.loc[y,'Day'] == 2:
        df_day.loc[y,'Day'] = 'Wednesday'
        y = y + 1
    elif df_day.loc[y,'Day'] == 3:
        df_day.loc[y,'Day'] = 'Thursday'
        y = y + 1
    elif df_day.loc[y,'Day'] == 4:
        df_day.loc[y,'Day'] = 'Friday'
        y = y + 1
    elif df_day.loc[y,'Day'] == 5:
        df_day.loc[y,'Day'] = 'Saturday'
        y = y + 1
    elif df_day.loc[y,'Day'] == 6:
        df_day.loc[y,'Day'] = 'Sunday'
        y = y + 1
    else:
        df_day.loc[y,'Day'] = 'Error'
        y = y + 1
df_day.head(15)

Advertisement

Answer

You’re chaining your indexes (e.g., dataframe[col_index][row_index].

In general, you should use

  • dataframe.loc[row_index, col_index]
  • dataframe.iloc[row_index, col_index]
  • dataframe.at[row_index, col_index]
  • dataframe.iat[row_index, col_index]

But in your case, you don’t need any of that. In fact, you rarely need to loop through a dataframe.

In your case, I would do:

day_names= {
    0: 'Monday',
    1: 'Tuesday',
    2: 'Wednesday',
    3: 'Thursday', 
    4: 'Friday',
    5: 'Saturday',
    6: 'Sunday'
}

df_day = (
    df.assign(Date=lambda df: pandas.to_datetime(df['Date']))
      .assign(WeekDayNum=lambda df: df['Date']).dt.weekday)
      .assign(WeekDayName=lambda df: df['WeekDayNum']).map(day_names))
)

Or, you could be more clever about how your use your date objects:

import numpy
import pandas
x = ['01/01/2020', '02/01/2020', '03/01/2020', '04/01/2020', '05/01/2020',
     '06/01/2020', '07/01/2020', '08/01/2020', '09/01/2020']
(
    pandas.DataFrame({'DateString': x, 'N': numpy.arange(len(x))})
        .assign(Date=lambda df: pandas.to_datetime(df['DateString'], format='%d/%m/%Y'))
        .assign(Weekday=lambda df: df['Date'].dt.strftime('%A'))
)

And that gives me:

   DateString  N       Date    Weekday
0  01/01/2020  0 2020-01-01  Wednesday
1  02/01/2020  1 2020-01-02   Thursday
2  03/01/2020  2 2020-01-03     Friday
3  04/01/2020  3 2020-01-04   Saturday
4  05/01/2020  4 2020-01-05     Sunday
5  06/01/2020  5 2020-01-06     Monday
6  07/01/2020  6 2020-01-07    Tuesday
7  08/01/2020  7 2020-01-08  Wednesday
8  09/01/2020  8 2020-01-09   Thursday
User contributions licensed under: CC BY-SA
4 People found this is helpful
Advertisement