3

input DF:

value1, value2
123L, 20
222S, 10
222L, 18

I want to make values in volumn value2 where in value1 is L letter negative, so I am trying to multiply them by -1

expexted result:

value1, value2
    123L, -20
    222S, 10
    222L, -18

my code

if np.where(DF['value1'].str.contains('L', case=False)):
    DF['value2'] = DF['value2'] * -1

but in output i am receiving all values in column value2 negative. How to implement this conditions only for selected rows ? thanks

cs95
  • 379,657
  • 97
  • 704
  • 746
sygneto
  • 1,761
  • 1
  • 13
  • 26

3 Answers3

3

You can use Boolean indexing with loc:

df.loc[df['value1'].str[-1] == 'L', 'value2'] *= -1

Alternatively, using pd.Series.mask:

df['value2'].mask(df['value1'].str[-1] == 'L', -df['value2'], inplace=True)

If you are keen on using np.where, this is possible but verbose:

df['value2'] = np.where(df['value1'].str[-1] == 'L', -df['value2'], df['value2'])

Notice np.where is already vectorised, you should not use it in conjunction with if.

jpp
  • 159,742
  • 34
  • 281
  • 339
1

str.endswith + loc

df.loc[[x.endswith('L') for x in df.value1], 'value2'] *= -1
df

  value1  value2
0   123L     -20
1   222S      10
2   222L     -18

mask

df['value2'] = df.value2.mask(df.value1.str.endswith('L'), -df.value2)
df

  value1  value2
0   123L     -20
1   222S      10
2   222L     -18
Community
  • 1
  • 1
cs95
  • 379,657
  • 97
  • 704
  • 746
1

The hack from replace more info

df.value1.replace({'L':-1,'S':1},regex=True)*df.value2.astype(int)
Out[183]: 
0   -20
1    10
2   -18
dtype: int64

--

Assign it back

df.value2*=df.value1.replace({'L':-1,'S':1},regex=True)
df
Out[187]: 
  value1  value2
0   123L     -20
1   222S      10
2   222L     -18
BENY
  • 317,841
  • 20
  • 164
  • 234