2

I have a df

cur    val
USD    50
GBP    100
EUR    150

I am trying to convert all values to GBP:

def sales_gbp(df):
    cur = df.cur
    value = df.val

    if cur == 'USD':
        return val*0.72
    elif cur == 'EUR':
        return val*0.85
    else:
        return val
    
df['value_GBP'] = df.apply(sales_gbp(df), axis=1)

But I get :

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

----> 5 if cur == 'USD':

df.dtypes return object for both cur and val. I've read this answer but I still can't apply the function to my df.

Jonas Palačionis
  • 4,591
  • 4
  • 22
  • 55

2 Answers2

4

I suggest use variable x in function for clear it is different variable like original df, then dont pass df to DataFrame.apply:

def sales_gbp(x):
    cur = x.cur
    val = x.val

    if cur == 'USD':
        return val*0.72
    elif cur == 'EUR':
        return val*0.85
    else:
        return val

df['value_GBP'] = df.apply(sales_gbp, axis=1)

Better is pass dict for mapping and for not match values by dict is return NaN, so replace them by 1:

d = {'USD':0.72, 'GBP':0.85}
df['value_GBP'] = df['cur'].map(d).fillna(1).mul(df['val'])
print (df)
   cur  val  value_GBP
0  USD   50       36.0
1  GBP  100       85.0
2  EUR  150      150.0

Or use fill_value=1 in Series.mul:

d = {'USD':0.72, 'GBP':0.85}
df['value_GBP'] = df['cur'].map(d).mul(df['val'], fill_value=1)
jezrael
  • 822,522
  • 95
  • 1,334
  • 1,252
2

You can also use the series directly:

Sample data

import pandas as pd

d = {'cur': {0: 'USD', 1: 'GBP', 2: 'EUR'}, 'val': {0: 50, 1: 100, 2: 150}}
df = pd.DataFrame(d)

Code

dct = {'GBP': 1, 'USD': 0.72, 'EUR': 0.85}
df['value_GBP'] = df['cur'].map(dct) * df['val']

Output

0     36.0
1    100.0
2    127.5
Andreas
  • 8,694
  • 3
  • 14
  • 38