2

I have a Dataframe that looks like this:

     Name    Flag  Other cols
0     Bob     N
1     Jack    N
2     Mike    Y
3     Mike    Y
4     Jack    Y

I would like to update a specific Name with a 0 or 1 based on Flag. This is the line of code that I tried

df[df['Name'] == 'Jack']['Name'] = np.where(df[df['Name'] == 'Jack']['Flag'].isin(['Y']), '0', '1')

which I would expect to return:

     Name    Flag  Other cols
0     Bob     N
1     1       N
2     Mike    Y
3     Mike    Y
4     0       Y

So in this instance, If name is Jack and Flag is Y then I want Jack to be updated to 0 and otherwise to 1.

The code works fine when I'm not trying to specify which Name to change for example:

df['Name'] = np.where(df['Flag'].isin(['Y']), '0', '1')

results in:

     Name   Flag  Other cols
0     1      N
1     1      N
2     0      Y
3     0      Y
4     0      Y

There is no error thrown, just that the dataframe doesn't get updated for some reason.

I also tried printing the np.where() portion and it returns the correct array of 0s and 1s so that doesn't appear to be the issue either.

greenteam
  • 305
  • 5
  • 16

2 Answers2

3

There is a warning when you do this:

In [11]: df[df['Name'] == 'Jack']['Name'] = np.where(df[df['Name'] == 'Jack']['Flag'].isin(['Y']), '0', '1')
/Users/hayd/.miniconda3/bin/ipython: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: http://pandas.pydata.org/pandas-docs/stable/indexing.html#indexing-view-versus-copy

which explains why it doesn't update df.

and suggests that you use loc as follows:

In [12]: df.loc[df['Name'] == 'Jack', 'Name'] = np.where(df[df['Name'] == 'Jack']['Flag'].isin(['Y']), '0', '1')

In [13]: df
Out[13]:
   Name Flag
0   Bob    N
1     1    N
2  Mike    Y
3  Mike    Y
4     0    Y
Andy Hayden
  • 359,921
  • 101
  • 625
  • 535
  • Ahh I did not see that warning. it appears to have gotten buried under some other logs I had. Thank you! – greenteam May 24 '19 at 19:50
1

This will work:

df.loc[df['Name'] == 'Jack', 'Name'] = np.where(df[df['Name'] == 'Jack']['Flag'].map(df['Flag']=='Y'), '0', '1')