How to apply a (potentially) different callable to each row in a pandas DataFrame

61 Views Asked by At

I have a number of DataFrames, each with the same number of rows. input_df contains input data, param_df contains the parameters used for calculations, and output_df contains output data. One of the columns in param_df contains the function that should be applied to each row.

In my simple MWE below, we want one of the functions to be applied to the first five rows, and the other function to be applied to the last five rows.

My question is how can I do this without the clumsy list comprehension? It seems like I should be able to use something like map or apply but I haven't worked out how to apply the callable on a per-row basis.

import pandas as pd
import numpy as np

def func_1(in_val, a, b):
    return in_val + a + b

def func_2(in_val, a, b):
    return in_val + (2 * (a + b))


input_df = pd.DataFrame(data=[1 for row in range(10)],
                  columns=["GR"])

output_df = pd.DataFrame(data=[np.nan for row in range(10)],
                  columns=["VCLGR"])

param_df = pd.DataFrame(data=[[5, 10] for row in range(10)],
                        columns=["x", "y"])

# Add the callables to the param_df
param_df["method"] = func_1
param_df.loc[5:, "method"] = func_2

# Compute the output for each row using the function specified
output_df["VCLGR"] = [param_df["method"][i](input_df["GR"][i], param_df["x"][i], param_df["y"][i]) for i in range(len(input_df))]

1

There are 1 best solutions below

0
MatBailie On

You could use a function that takes a dataframe row as a parameter, and use that to invoke the function(s) stored in the dataframe...

def indirect(row):
  return row['method'](row['GR'], row['x'], row['y'])

output_df["VCLGR_2"] = pd.concat(
    [
      param_df,
      input_df
    ],
    axis=1
  ).apply(
    indirect,
    axis=1
  )

https://trinket.io/python3/0183496178