11

Using this simple line of code, I keep on getting a SettingWithCopyWarning error that than carries through my whole code.

#make email a string
df['Email Address'] = df['Email Address'].astype(str)

C:\Users\xxx\AppData\Local\Continuum\Anaconda2\lib\site-packages\ipykernel\__main__.py:2: 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: http://pandas.pydata.org/pandas-docs/stable/indexing.html#indexing-view-versus-copy
  from ipykernel import kernelapp as app

I went through the documentation, but can't make it work with loc. The code below is wrong.

df.loc['Email Address'] = df.loc['Email Address'].astype(str)

Please excuse if this is a duplicate question - I searched it on stackoverflow, but couldn't find one that addresses loc and astype.

jeangelj
  • 4,338
  • 16
  • 54
  • 98

2 Answers2

22

Your issue isn't with how you are making the assignment. It is with the dataframe prior to assignment. At some point prior to the assignment, you created df in such a way that it became a view into another dataframe. You can verify this with bool(df.is_copy)

If you are ok with df being a separate thing with no linkages to data in other dataframes...

df = df.copy()

Then proceed to make your assignment.

piRSquared
  • 285,575
  • 57
  • 475
  • 624
  • Wow - that's correct, I did create a new dataframe from a filter of a previous dataframe df = raw[raw['COUNTRY'].isin(['United States', 'Canada']) - is the issue with how I did that or do I need to do the df = df.copy() no matter what? Thank you – jeangelj Jul 11 '17 at 15:07
  • Why should this trigger the warning, anyway? Would doing `df = df.copy()` increase RAM usage since it is no longer just a "view"? When you do `.astype()` when `bool(df.is_copy)==True`, is it secretly performing `.copy()` under the hood and therefore the warning is triggered, since it copies the df without your explicit telling it to do so? – Corey Levinson May 13 '19 at 20:30
  • Yes, there are many ways to trigger a copy. The point is that it is inconsistent and difficult to predict. `df.copy()` is a pass to just get the copy without messing around. – piRSquared May 13 '19 at 20:33
2

Update 03/21

I believe this is the correct solution with loc

df.loc[:, 'Email Address'].astype(str)

Pysnek313
  • 134
  • 14