-1

Lets say i have a dataframe df with columns a, b like below: a b 1 4 2 5 3 6

Lets assume we have similar function which returns 2 values

fun calc(a, b, type):
 if type=='both':
  c=a+b
  d=a-b
return c, d

how to store the returned values to a new column in dataframe df i tried below syntax, but getting error mentioning

df[['c', 'd']] = df['a', 'b'].apply(calc, type='both', axis=1)

but getting error as calc got an unexpected keyword argument 'axis'

Henry Ecker
  • 34,399
  • 18
  • 41
  • 57
  • Neither of the code snippets run. functions are defined with `def` not `fun` in python. I think you also meant `df[['a', 'b']].apply(calc...` to select those two columns. – Henry Ecker May 07 '21 at 02:31
  • 1
    See: [pandas apply function that returns multiple values to rows in pandas dataframe](https://stackoverflow.com/questions/23690284/pandas-apply-function-that-returns-multiple-values-to-rows-in-pandas-dataframe) – Henry Ecker May 07 '21 at 02:31
  • Although this isn't related to your question, I would suggest that you don't use `type` as a keyword argument for your function as `type` is a built-in function in Python. – Derek O May 07 '21 at 04:14

1 Answers1

0

You use the following code

df[['c', 'd']] = df['a', 'b'].apply(calc, type='both', axis=1)

There are several issues:

  1. To select multi columns, you need to use a list of column names, like df[['a', 'b']].
  2. pandas.DataFrame.apply() doesn't have type argument.
  3. Since you use axis=1, calc should only take one argument which is the row of dataframe.

If you want to pass extra arguments to calc, you can do in two ways

  1. Use args argument of apply()
def calc(row, type):
    a = row['a']
    b = row['b']

    if type=='both':
        c = a+b
        d = a-b

    return c, d

df[['c', 'd']] = df[['a', 'b']].apply(calc, args=('both',), axis=1, result_type='expand')
  1. You can use lambda funciton
def calc(row, type):
    a = row['a']
    b = row['b']

    if type=='both':
        c = a+b
        d = a-b

    return c, d

df[['c', 'd']] = df[['a', 'b']].apply(lambda row: calc(row, 'both'), axis=1, result_type='expand')

At last, since type is a built-in function of Python. You'd better not use it as variable name.

A MRE

import pandas as pd


df = pd.DataFrame({'a': [1, 2, 3], 'b': [4, 5, 6]})

def calc(row, type):
    a = row['a']
    b = row['b']

    if type=='both':
        c = a+b
        d = a-b

    return c, d

df[['c', 'd']] = df[['a', 'b']].apply(lambda row: calc(row, 'both'), axis=1, result_type='expand')

df[['e', 'f']] = df[['a', 'b']].apply(calc, args=('both',), axis=1, result_type='expand')
print(df)

   a  b  c  d  e  f
0  1  4  5 -3  5 -3
1  2  5  7 -3  7 -3
2  3  6  9 -3  9 -3
Ynjxsjmh
  • 28,441
  • 6
  • 34
  • 52
  • Tried both suggesstions: getting error case1 - TypeError calc() got an unexpected keyword argument 'axis' case 2 - TypeError: () got an unexpected keyword argument 'axis' – crybaby May 07 '21 at 06:59
  • @crybaby I added a MRE in my answer. – Ynjxsjmh May 07 '21 at 13:42