2

I have not received this copy warning with other functions and I have not found a way to address it.

Here is my code:

div_df.loc[:,"Ann.Date"] = pd.to_datetime(div_df.loc[:,"Ann.Date"], format='%d %b %Y')

/volume1/homes/id/venv/lib/python3.8/site-packages/pandas/core/indexing.py:1843: 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.obj[item_labels[indexer[info_axis]]] = value

I have not found a solution anywhere other than the following:

div_df.loc[:,"Ann.Date"] = pd.to_datetime(div_df.loc[:,"Ann.Date"], format='%d %b %Y', errors='coerce')
SeaBean
  • 22,547
  • 3
  • 13
  • 25
mrkgoh
  • 31
  • 2
  • 7
  • Simply use `df["Date"] = pd.to_datetime(df["Date"], format='%d %b %Y')`. – Ynjxsjmh Apr 14 '21 at 07:50
  • @Ynjxsjmh I tried it and it is the same warning. :1: 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 div_df["Ann.Date"] = pd.to_datetime(div_df["Ann.Date"], format='%d %b %Y') – mrkgoh Apr 14 '21 at 09:02
  • Using .loc() is generally a solution to cater for the SettingWithCopyWarning If it still got the warning, can't imagine why removing the .loc could solve it. In your case, probably your div_df is itself a copy of slice from some other dataframe. You may need to try making a copy of it by e.g. div_df = another_df[some_selection_mask].copy() – SeaBean Apr 14 '21 at 09:13
  • Take a look at [this answer](https://stackoverflow.com/a/53954986/15070697). The last sentence: `The solution here is to either make a copy() of df, or use loc, as before.` – SeaBean Apr 14 '21 at 09:24
  • 1
    @seabean thank you. I used div_df = another_df.copy(deep=True) and it fixed the issue. – mrkgoh Apr 14 '21 at 10:21
  • That's good you solved it. The default of .copy() is already with `deep=True`, so I didn't tell you to add this parameter. – SeaBean Apr 14 '21 at 11:31
  • I included some very good reference below. You can take a look. Please also remember to [accept the answer](https://stackoverflow.com/help/someone-answers) if you think useful to you. – SeaBean Apr 14 '21 at 12:00

1 Answers1

4

As mentioned in the discussion in comments, the root cause is probably your dataframe div_df is built from a slice of another dataframe. Most commonly, we either solve this kind of SettingWithCopyWarning problem by using .loc or using .copy()

Now, you have already used .loc and still get the problem. So, suggest to use .copy() when you created the dataframe div_df, with syntax, like:

div_df = another_df[some_selection_mask].copy()

Here, probably you have specified some filtering condition on the base df so that the final df created is a slice of that base df. Or, the base df is already a slice of another df. You can use .copy() without specifying deep=True since it is the default. You can refer to this webpage for more information on it.

The parameter deep determines if you want a view (deep=False) or copy (deep=True). deep is True by default, so you can omit it to get a copy

The SO page I mentioned in comment, i.e. this post offers very good info. The webpage I included above has a very comprehensive information and solutions for this topic.

SeaBean
  • 22,547
  • 3
  • 13
  • 25
  • I have been looking for this comment long time! I had the same issue because I did something like df2=df1.query('xxxxxxx') before the datetime transform. I changed it to df2=df1.query('xxxxxxx').copy() and it no longer complains. – Zhongjie Shen Aug 04 '23 at 18:27