Apply Lambda on 2 dataframe columns in one line

Viewed 1143
r_c = 'newyork sanfrancisco losangeles'.split()

def my_is_r_c(c):
    return c.replace(' ', '').lower() in r_c

train['is_r_c'] = train['c_o'].apply(lambda x: 1 if my_is_r_c(x) else 0)
train['is_r_c'] = train['c_d'].apply(lambda x: 1 if my_is_r_c(x) else 0)

Hi guys

Is there a way to apply the lambda for both columns ['c_o'] and ['c_d'], in only one line?

thx in advance

4 Answers

You could do that useing applymap like this:

df[['is_r_c', 'is_r_d']]= df[['c_o', 'c_d']].applymap(lambda x: 1 if my_is_r_c(x) else 0)

In case you want the columns combined, and there in fact is only one result column, which should contain 1 if your function evaluates to 1 for at least one of the columns, you can do that with a small variation like this:

df[['is_r_c']]= df[['c_o', 'c_d']].applymap(lambda x: 1 if my_is_r_c(x) else 0).max(axis='columns')

Using df.filter:

df.filter(regex='c_[od]').apply(lambda x: 1 if my_is_r_c(x) else 0)

You can rewrite the function like this:

# use of `isin` allows passing a series
def my_is_rc(c):
    return c.replace(' ','').isin(r_c).astype(int)

# apply along the columns    
train[['is_rc','is_rd']] = train[['c_o','c_d']].apply(my_is_rc)

Or just forget about apply and:

train[['is_rc','is_rd']] = train[['c_o','c_d']].isin(r_c).astype(int)

You could do it by creating two (instead of one as in your question) new columns and using fancy indexing on the columns:

import pandas as pd

train = pd.DataFrame(dict(c_o=[1, 2, 3], c_d=[4, 5, 6]))
train
train[['x_1', 'x_2']] = train[['c_o', 'c_d']].apply(lambda x: x**2)
train

Cheers.

Related