How to add or combine two columns into another one in a dataframe if they meet a condition

Viewed 65

I'm new to this, so this may sound weird but basically, I have a large dataframe but for simplification purposes let's assume the dataframe is this:

import pandas as pd
import numpy as np

dfn = pd.DataFrame({'a':[1,2,3,4,5],
                   'b':[6,7,8,9,10],
                   'c':np.nan})
dfn

Output:

    a   b   c
0   1   6   NaN
1   2   7   NaN
2   3   8   NaN
3   4   9   NaN
4   5   10  NaN

What I want to do is to fill in values in the 'c' column based off of a condition, namely if the corresponding row value in 'a' is odd, then add it to the corresponding row value 'b' and input into 'c', else, just use the 'a' value for 'c'.

What I currently have is this:

for row in range(dfn.shape[0]):
    if dfn.loc[row]['a']%2!=0:
        dfn.loc[row]['c']=dfn.loc[row]['a']+dfn.loc[row]['b']
    else:
        dfn.loc[row]['c']=dfn.loc[row]['a']

dfn

Output:

    a   b   c
0   1   6   NaN
1   2   7   NaN
2   3   8   NaN
3   4   9   NaN
4   5   10  NaN

Nothing seems to happen here and I'm not entirely sure why.

I've also tried a different approach of:

is_odd=dfn[dfn['a']%2!=0]
is_odd['c'] = is_odd['a'] + is+odd['b']

is_odd

Here, weirdly I get the right output:

    a   b   c
0   1   1   2
2   3   3   6
4   5   5   10

But when I call dfn again, it comes out with all NaN values.

I've also tried doing it without using a variable name and nothing happens.

Any idea what I'm missing or if there's a way of doing this?

Thanks!

4 Answers

Use numpy where, which works for conditionals. It is akin to an if statement in Python, but significantly faster. I rarely use iterrows, since I don't find it as efficient as numpy where.

 dfn['c'] = np.where(dfn['a']%2 !=0, 
                     dfn.a + dfn.b,
                     dfn.a)


    a   b   c
0   1   6   7
1   2   7   2
2   3   8   11
3   4   9   4
4   5   10  15

Basically, the first line in np.where defines your condition, which in this case is finding out if the 'a' column is an odd number. If it is, the next line is executed. If it is an even number, then the last line is executed. You can think of it as an if-else statement.

Use Series.mod and Series.where to get a copy of column b with 0 where there is an even value in a, then we add this serie to a.

dfn['c'] = dfn['b'].where(dfn['a'].mod(2).eq(1), 0).add(dfn['a'])
print(dfn)
   a   b   c
0  1   6   7
1  2   7   2
2  3   8  11
3  4   9   4
4  5  10  15

Alternative

dfn['c'] = dfn['a'].mask(dfn['a'].mod(2).eq(1), dfn['a'].add(dfn['b']))

dfn.loc[row]['c']=... is always wrong. dfn.loc[row] may be either a copy or a view, so you cannot know what will happen. The correct way is:

dfn.loc[row, 'c']=...

Anyway here you should avoid the iteration and use np.where as suggested by other answers

Here is my solution which is close to original thought of the author of the question, hope it can be helpful

def oddadd(x):
    if x['a']%2!=0:
        return x['a']+x['b']
    else:
        return x['a']
dfn["c"] = dfn.apply(oddadd,axis=1)

Related