【问题标题】:What do you mean by "The truth value of a Series is ambiguous?你是什​​么意思“一个系列的真值是模棱两可的?
【发布时间】:2019-12-26 10:02:04
【问题描述】:

我在 Python 编程方面大约有 2 周的时间。试图在论坛上搜索我标题中所述的错误,但我仍然不明白我的代码有什么问题。

ValueError:Series 的真值不明确。使用 a.empty、a.bool()、a.item()、a.any() 或 a.all()。

我正在尝试做的事情:

  • 在我的字典中插入一个定义的函数来确定 基于 DataFrame ['LocalCurrency'] 值的阈值级别。

  • 如果我的 DataFrame ['Country'] 包含字典中的键(例如 新加坡),运行函数并将返回值放在新列中 称为“阈值水平”。

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'])

非常感谢您的意见,谢谢!

【问题讨论】:

标签: python ambiguous


【解决方案1】:

实际错误 - 你看 - 被提出,因为你试图使用系列作为字典的键。为了避免它 - 你必须从这个系列中获得一个元素。 您的代码中还有很多其他问题。 你可以这样解决:

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])

另外 - 如果您没有在 dict 中包含所有国家/地区 - 更好的方法是使用 apply,像这样,它对于大 DataFrame 的工作速度会更快,而且 - 它看起来更好:

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)

另外,如果您的所有国家/地区都在 dict 中,您可以使用:

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

以下是如何重写函数及其用法[添加以更详细地解释应用函数的行为]:

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)

【讨论】:

  • 像魅力一样工作!但是,有一些我并不陌生的函数,如 lambda 和 df.method "apply"。需要了解有关上述主题的更多信息。如果我再次有任何问题,可以就这段代码向您咨询吗?
  • @Zongyi 当然-没关系-随时问任何问题。 Apply 方法 - 分别对 DataFrame 的每一行应用一个函数。 (pandas.pydata.org/pandas-docs/stable/reference/api/…) Lambda 函数 - 只是内联函数,您可能会将其视为简单函数:some_func = lambda x: x+2 等同于:def some_func(x): return x+2 (w3schools.com/python/python_lambda.asp)
  • 嗨,斯塔斯,我刚刚阅读了 lambda 函数。似乎 lambda 是将函数重写为单个句子的不同方式。但是我们通过def写了一个函数,为什么还需要lambda呢?当我从您的代码中删除 lambda 时,它会弹出一个错误,指出 'Series' 对象是可变的,因此它们不能被散列。我很困惑哈哈。 df['ThresholdLevel'] = df.apply(lambda x: convert_thres(x['Country'], x['LocalCurrency']), axis =1) VS df['ThresholdLevel'] = df.apply(convert_thres(df['Country'], df['LocalCurrency']), axis =1)
  • 你正确理解了 lambda 函数。对于应用-您可以考虑一下,例如遍历行并为每个行应用函数。因此,您正在应用的函数的输入 - 是数据框的唯一一行。这就是为什么 - lambda 有效 - x 这里 - 是单行,而不是整个 DataFrame。我还添加了另一种编写和使用函数的方式——它应该更好地解释应用行为。请检查一下,希望清楚。
【解决方案2】:
  1. 熊猫并不容易。我不是说你不应该使用它,如果你 只学了 2 周的 Python,但你会有很多关于 Python 的问题 如果您刚刚开始,请使用 pandas。
  2. 不要在键上使用i 进行迭代。通常i 用于索引。你似乎 遍历国家列表。也许把它命名为国家。
  3. 您可能想要使用applymapapply
  4. 在 convertsgp 中尝试添加 else 以提高可读性。
  5. 这行有问题 df.loc[(df['Country']== i, 'Threshold Level'] = mydict [i](df['LocalCurrency'])df.loc[后面应该没有(

【讨论】:

  • 感谢汤姆的建议。由于我还在学习,如果我问任何愚蠢的问题,请原谅我。 1)对于第 2 点,你是什么意思 i 只是索引?如何更好地编写代码来访问字典中的键?由于我是 Excel 的重度用户,因此将键视为索引(Excel 标头)而值是其对应的元素(标头下方的 Excel 值)对我来说非常直观。希望你明白我在说什么哈哈。 2) 对于第 4 点,我不确定要为 Else 语句插入什么,因为我已经涵盖了我的论点中的所有值。我可以做些什么来管理 Else 语句?
  • 按照惯例,您将使用i, v in enumerate(lst),其中i 代表索引,v 代表值。 el 用于列表元素,k 用于键。如果list(mydict.keys()) 是国家/地区列表,则for country in list(mydict.keys()) 更有意义。可读性很重要。至于其他声明,这只是一个建议。您编写它的方式很好,但是如果由于某种原因没有定义y 怎么办,因为它总是在 if/elif 块中定义? IDE 建议进行此编辑。尝试使用 PyCharm 并遵循它的建议。祝你好运!
猜你喜欢
  • 2015-09-14
  • 1970-01-01
  • 1970-01-01
  • 2019-05-18
  • 1970-01-01
  • 2018-12-03
  • 1970-01-01
  • 1970-01-01
  • 2022-09-28
相关资源
最近更新 更多