How to control which formula to apply in a function depending on the current value of two pandas dataframe arguments?

Question:

I’ve got a function f(a, b) that is taking two pandas dataframes to apply different formulas to the values like this:

def f(a, b):
   if a > 0 and b > 0:
      return a + b
   elif a > 0 and b < 0:
      return a - b
   elif a < 0 and b > 0:
      return a * b
   elif a < 0 and b < 0:
      return a / b
   else:
      print('bad')

dfa = pd.DataFrame({'a':[1, 1]})
dfb = pd.DataFrame({'b':[2, 2]})
f(dfa,dfb)

The issue here in particular is, that I’d need the current value that is processed in the function to branch, however, using the and operator leads to this below.

“The truth value of a Series is ambiguous. Use a.empty, a.bool(), a.item(), a.any() or a.all()”

and using & is leading to a

“cannot compare [type] array with a scalar of type [bool]”

Edit:

Considering the answers, I starting to realize that my minimal example might not transport my intention very well.

def f(a, b):
  if a > 0 and b > 0:
    X = operationA()
  elif a > 0 and b < 0:
    X = operationB()
  elif a < 0 and b < 0:
    X = operationC()
  elif a < 0 and b < 0:
    X = operationD()
  else:
    print('bad')

  Y = operationY()
  return X, Y

# both dataframes are part of a training example label example = (a, b)
df_label_partA = pd.DataFrame({'a':[1, 1, -1, -1]})
df_label_partB = pd.DataFrame({'b':[1, -1, 1, -1]})
f(df_label_partA, df_label_partB)

the data frames can’t be considered separately as each is part of a list of labels (basically a tuple split up into 2 lists)

Asked By: Markus

||

Answers:

Try this:

pd.concat([dfa,dfb], axis=1).apply(lambda x: f(*x), axis=1)

Outputs:

0    3
1    3
dtype: int64
Answered By: Grzegorz Skibinski

You can try this

def f(a, b):
   if all(a > 0) and all(b > 0):
      return dfa.a + dfb.b
   elif all(a > 0) and all(b < 0):
      return dfa.a - dfb.b
   elif all(a < 0) and all(b > 0):
      return dfa.a * dfb.b
   elif all(a < 0) and all(b < 0):
      return dfa.a / dfb.b
   else:
      print('bad')

dfa = pd.DataFrame({'a':[1, 1]})
dfb = pd.DataFrame({'b':[2, 2]})
f(dfa,dfb)

output

0    3
1    3
dtype: int64
Answered By: Ch3steR
Categories: questions Tags: ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.