Search code examples
pythonambiguous

What do you mean by "The truth value of a Series is ambiguous?


I'm about 2 weeks into Python programming. Tried to search on the forum about the error stated in my title however I still do not understand what is wrong with my code.

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

What I'm trying to do:

  • Insert a defined function into my dictionary which is to determine the threshold level based on the DataFrame ['LocalCurrency'] value.

  • If my DataFrame ['Country'] consist of a key from the dictionary (e.g. Singapore), run the function and place the returning value in a new column called 'Threshold level'.

def convertsgp(x):    
    if x <= 99:
        y = 'Nominal'
    elif x <= 349:
        y = 'Threshold 1'
    elif x <= 1399:
        y = 'Threshold 2'
    elif x > 1400:
        y = 'Threshold 3'
    return y



mydict = {'Singapore': convertsgp }


for i in list(mydict.keys()):
    df.loc[(df['Country']== i, 'Threshold Level'] = mydict [i](df['LocalCurrency'])

Your inputs are greatly appreciated, thank you!


Solution

  • Actual error - you see - is raised, because you are trying to use series as a key of the dictionary. To avoid it - you have to get a single element from this series. There are, also, a lot of other problems in your code. You can solve it like this:

    import pandas as pd 
    data = {
            'Threshold Level':[0, 0, 0, 0, 0], 
            'Country':['Itally', 'Singapore', 'Ukraine', 'USA', 'England'],
            'LocalCurrency': [100, 2000, 392, 3,23 ]
            } 
    
    # Convert the dictionary into DataFrame  
    df = pd.DataFrame(data) 
    
    def convertsgp(x):
    
        if x <= 99:
            y = 'Nominal'
        elif x <= 349:
            y = 'Threshold 1'
        elif x <= 1399:
            y = 'Threshold 2'
        elif x > 1400:
            y = 'Threshold 3'
        return y
    
    
    mydict = {'Singapore': convertsgp }
    
    
    for i in list(mydict.keys()):
        local_currency = df.loc[df['Country']== i]['LocalCurrency']
        df.loc[df['Country']== i, 'Threshold Level'] = mydict[i](local_currency[1])
    

    Also - if you don't have all the countries in dict - a better approach is to use apply, like this, it'll work much faster for big DataFrames and, also - it looks better:

    import pandas as pd 
    data = {
            'ThresholdLevel':[0, 0, 0, 0, 0], 
            'Country':['Itally', 'Singapore', 'Ukraine', 'USA', 'England'],
            'LocalCurrency': [100, 2000, 392, 3,23 ]
            } 
    
    # Convert the dictionary into DataFrame  
    df = pd.DataFrame(data) 
    
    def convertsgp(x):
        if x <= 99:
            y = 'Nominal'
        elif x <= 349:
            y = 'Threshold 1'
        elif x <= 1399:
            y = 'Threshold 2'
        elif x > 1400:
            y = 'Threshold 3'
        return y
    
    mydict = {'Singapore': convertsgp}
    
    def apply_corresponding_function(country, value_to_apply_on):
    
        try: # lets try to get function we need to apply
            function_to_apply = mydict[country] # if there's no such key in dictionaries it'll raise an error
            return function_to_apply(value_to_apply_on) 
    
        except: # this will be executed, if operations after 'try' raised any errors:
            return False
    
    
    df['ThresholdLevel'] = df.apply(lambda x: apply_corresponding_function(x['Country'], x['LocalCurrency']), axis =1)
    

    Also, if you have all your countries in dict you may use:

    df['Threshold Level'] = mydict[df['Country'].any()](df['LocalCurrency'])
    

    Here's how you can rewrite function and it usage [ added to explain the behaviour of apply function in more details]:

    def function_to_be_applied(dataframe_row):
    
        country = dataframe_row['Country']
        value_to_apply_on = dataframe_row['LocalCurrency']
    
        try: # lets try to get function we need to apply
            function_to_apply = mydict[country] # if there's no such key in dictionaries it'll raise an error
            return function_to_apply(value_to_apply_on) 
    
        except: # this will be executed, if operations after 'try' raised any errors:
            return False
    
    
    df['ThresholdLevel'] = df.apply(function_to_be_applied, axis = 1)