how do i use multiple columns of a df as input to a function?

ihave a dataframe full of numerical values. and i want to apply a function (delta) it takes 6 arguements.

calls['delta'] = calls[['callput','underlyinglast','strike','yte','rfr','hvol90']].apply(delta,axis=1)

i keep getting the error

TypeError: delta() missing 5 required positional arguments: 'S', 'K', 't', 'r', and 'sigma'

i also tried a variant with lambda, but i keep getting the error. i think because its trying to apply the function to each individual value, instead of the row.

can i do this any other way? (without iterrows, its so slow, its a df with 500k rows)

>Solution :

apply with axis=1 calls your function for each row, but with 1 parameter: the row as a Series object. So you either need to revise your function definition to take a single row instead of multiple parameters, or wrap your function call in a lambda function which extracts the values from each row and calls the function with them.

  1. Revising your function to take a single row
    Instead of this:

    def delta(S, K, t, r, sigma):
        # ... 
    

    do this:

    def delta(row):
        S, K, t, r, sigma = row.tolist()
        # ...
    
  2. Wrapping your function call in a lambda function
    Instead of this:

    calls['delta'] = calls[['callput','underlyinglast','strike','yte','rfr','hvol90']].apply(delta,axis=1)
    

    do this:

    calls['delta'] = calls[['callput','underlyinglast','strike','yte','rfr','hvol90']].apply(lambda row: delta(*row), axis=1)
    

    (the trick there is to use lambda row: delta(*row) instead of just delta; *row basically "spreads" the items in row across the separate arguments of delta)

Leave a Reply