1

So I want to conditionally replace values in pandas.DataFrame using mask function, so imagine we have this dataframe:

     Col1           Col2
0    Qeq            10
1    Qeq            20
2    Qwa            30

What I want is to have an ability to replace all values where Col1 == 'Qwa' to f-string referencing OLD value dynamically. So my desired format is: "-{value}" and desired output is:

     Col1           Col2
0    Qeq            10
1    Qeq            20
2    Qwa            -30

Is it possible using .mask function? I've tried following:

# This works but new value in this case is hardcoded
df['Col2'].mask(df['Col1'] == 'Qwa', other='-' + df['Col2'])
# This does not work as it evaluates whole series in a f-string
df['Col2'].mask(df['Col1'] == 'Qwa', other=f'-{df["Col2"]}')
4
  • why not try to filter out the column, then use map()/apply() to effect the change you want? Commented Feb 16, 2021 at 14:24
  • 1
    What do you mean by dynamically? If you mean Excel style where you change Col1, Col2 automatically changes, then no, it's not supported. Commented Feb 16, 2021 at 14:26
  • @Ade_1 Is it possible to reference old value in f-string-like and pass it as an argument? Commented Feb 16, 2021 at 14:28
  • @QuangHoang By "dynamically" i mean an ability to supply any f-string-like format to be replaced in dataframe/series. NEW-VALUE(OLDVALUE:{value}) or any string like this Commented Feb 16, 2021 at 14:29

2 Answers 2

2

How about apply the format function:

df['Col2'].mask(df['Col1'] == 'Qwa', other=df['Col2'].apply('-{}'.format))

Output:

0     10
1     20
2    -30
Name: Col2, dtype: object

Or

df['Col2'].mask(df['Col1'] == 'Qwa', other=df['Col2'].apply('*{}'.format))

Output:

0     10
1     20
2    *30
Name: Col2, dtype: object
Sign up to request clarification or add additional context in comments.

Comments

1

Imagine this df:

In [63]: df
Out[63]: 
  Col1  Col2
0  Qeq    10
1  Qeq    20
2  Qwa    30
3  Qwa    40

You can something like, using df.loc:

In [66]: df.loc[df.Col1.eq('Qwa'), 'Col2'] = df.loc[df.Col1.eq('Qwa'), 'Col2'].mul(-1)

In [67]: df
Out[67]: 
  Col1  Col2
0  Qeq    10
1  Qeq    20
2  Qwa   -30
3  Qwa   -40

1 Comment

That's nice! Although, I need to work with strings and replace them via pattern using old values

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.