3

I came across this problem at work today and I would like to know if there is an efficient way to do this.

Basically I have a dataframe which look like this

df = pd.DataFrame([1,2,3], columns = ['a'])

I also have a function that returns a tuple. (Make note that this is only a minimal example, my problem is different)

compute = lambda x: (2*x, 3*x)

I need to find a way to do something that would ideally look like this:

(df['b'], df['c']) = df['a'].apply(compute)

Unfortunately, this syntax doesn't work and I can't wrap my head around another way to do it.

The only similar problem is this , but the solution seems really 'hacky' and I am convinced there is a better way to do it.

Thank you!!

  • Could do something like `df['b'], df['c'] = zip(*df['a'].map(compute))`, but it will probably be slower than just using a vectorized method to create each. – user3483203 Jun 26 '19 at 15:12

3 Answers3

8

IIUC, you can try with:

compute = lambda x: (2*x, 3*x)
df[['b','c']]=pd.DataFrame(df.a.apply(compute).tolist()) #thanks harvpan
#df[['b','c']]=pd.DataFrame(df.a.apply(compute).values.tolist())
print(df)

   a  b  c
0  1  2  3
1  2  4  6
2  3  6  9
anky
  • 74,114
  • 11
  • 41
  • 70
3

Another way

df=df.reindex(columns=df.columns.tolist()+['b','c'])
df[['b','c']]=list(map(compute,df.a))
df
Out[107]: 
   a  b  c
0  1  2  3
1  2  4  6
2  3  6  9
BENY
  • 317,841
  • 20
  • 164
  • 234
0

A simple way

df[['b','c']] = df['a'].apply(compute).tolist()