0

My data frame looks like this:

+------+------+------+-----------+
| val1 | val2 | val3 |   col1    |
+------+------+------+-----------+
|    3 |    1 |    1 | something | 
|    4 |    2 |    1 | sth else  |
|    2 |    2 |    3 | something | 
|    3 |    1 |    1 | sth else  |
|    2 |    2 |    1 | something | 
+------+------+------+-----------+

I want to insert values into 3 different columns if they meet a condition (mask).

For the first 2 columns it works, so inserting usual strings is fine. How do I insert the product of multiple values from other columns of the same row.

So this does work for Issue and Type but Value does not work:

mask = (df.col1 == 'something')
df[['Issue','Type','Value']] = np.where( mask[:, None], ['sth','One', str(np.prod(df.iloc[:, 0:3], axis=1))], ['','',''])

In this case I want to insert the multiplication of val1, val2 and val3 within the same row as string into Value.

Desired output:

+------+------+------+-----------+-------+------+-------+
| val1 | val2 | val3 |   col1    | Issue | Type | Value |
+------+------+------+-----------+-------+------+-------+
|    3 |    1 |    1 | something | sth   | One  |     3 |
|    4 |    2 |    1 | sth else  |       |      |       |
|    2 |    2 |    3 | something | sth   | One  |    12 |
|    3 |    1 |    1 | sth else  |       |      |       |
|    2 |    2 |    1 | something | sth   | One  |     4 |
+------+------+------+-----------+-------+------+-------+

PS.: Sorry about the headline, difficult to describe shortly.

2
  • 1
    Can you share example of input? You just need that for minimal reproducible example Commented Apr 17, 2018 at 14:00
  • thought the output would explain enough, sorry. Added input Commented Apr 17, 2018 at 14:18

4 Answers 4

2

You can do it with assign and combine_first

df.combine_first(df.assign(**dict(zip(['Issue','Type','Value'],['sth','One', np.prod(df.iloc[:, 0:3], axis=1).values]))).loc[mask,:])
Sign up to request clarification or add additional context in comments.

Comments

1

You can do this simply using the pandas .loc indexer function:

mask = (df.col1 == 'something')

df.loc[mask,'Issue']='sth'
df.loc[mask,'Type']='One'
df.loc[mask,'Value']=df.loc[mask,'val1']*df.loc[mask,'val2']*df.loc[mask,'val3']

Comments

0

This would require multiple assigns but it does the job:

values = ['val1', 'val2', 'val3']
results = df.val1 * df.val2 * df.val3

df = df.assign(Issue=np.where(mask, 'sth', '')).assign(Type=np.where(mask, 'sth', '')).assign(Value=np.where(mask, results, ''))

Value will be str automatically due to value of other argument in np.where.

Comments

0

This requires the reindexing, and might not be efficiënt for big sets, but should do the job!

df = df.reindex(columns = ['val1', 'val2', 'val3', 'col1', 'Issue','Type','Value'])
df['Issue'], df['Type'], df['Value'] = zip(*df[['val1', 'val2', 'val3', 'col1']].apply(lambda x: ('sth', 'One' , str(np.prod(x[:3])) ) if x[3] == 'something' else (None,None,None), axis = 1))

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.