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
  • 330,695
  • 80
  • 606
  • 657
sygneto
  • 1,667
  • 1
  • 10
  • 21

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
  • 147,904
  • 31
  • 244
  • 302
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
  • 330,695
  • 80
  • 606
  • 657
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
  • 296,997
  • 19
  • 147
  • 204