5

I have a very simple problem. I would like to change a value in a given column of a given row of a pandas data frame. I try to do it in the following way:

df['column3'].loc[this_date] = val

As a result I get the following warning:

SettingWithCopyWarning: A value is trying to be set on a copy of a slice from a DataFrame

My interpretation of this warning is that by using columns name ('column3') and loc I do not really access (refer to) the desired cell of the data frame. Instead, I create an object which is a copy of the "cell" object and then I try to change the value associated with this "copy-object".

What I do not understand is that it seems to work. In spite on the fact that pandas writes me that I try to modify the copy, I do modify the original data frame.

My question is how to make sure that I am really doing what I would like to do and how to do it in a "correct" way so that the pandas does not complain?

Roman
  • 124,451
  • 167
  • 349
  • 456
  • 1
    Shouldn't it be `df.loc[this_date,'column3'] = val`? Your version is different from the docs: http://pandas.pydata.org/pandas-docs/stable/indexing.html – EdChum Oct 30 '14 at 16:14
  • 1
    The fact it works is incidental, it may not work which is why you get the warning, please try my previous comment, there should be no warning – EdChum Oct 30 '14 at 16:26

1 Answers1

1

The reason of getting the warning is that df itself is a copy of some other dataframe object. I guess that you have some original dataframe df_origin and you get df from df_origin by some operation such as slicing. So df is a copy of df_origin. Then you try to set some value to df and the warning raises to tell you that this would not change the value in the original dataframe df_origin. One solution is to use a single variable to point to the dataframe object before and after slicing if you don't care for df_origin. Otherwise you can suppress the warning by pd.set_option('mode.chained_assignment', None)

Your way of setting value is fine, along with the following ones:

 df.ix[this_date, 'column3'] = val
 df.loc[this_date, 'column3'] = val
 df.at[this_date, 'column3'] = val
Yang
  • 114
  • 4
  • the warning is shown because chained indexing is not fine! it depends on the underlying data (whether it is s view) and if it's mixed dtype. If these are conditions hold then you will be setting a copy, hence the warning. The reason to not do chained indexing EVER is that there is no guarantee that your setting will work! there are a multitude of other indexing options available. – Jeff Nov 01 '14 at 00:59