【问题标题】:ValueError in For Loop's If Condition with two boolean arrays带有两个布尔数组的 For 循环的 If 条件中的 ValueError
【发布时间】:2020-01-11 21:40:00
【问题描述】:

我正在运行一个带有 If 语句的 For 循环,其中包括两个布尔数组来创建一个新数组。

我已经尝试了在 StackOverflow 上可以找到的所有解决方案,将 & 与 Logical_and 或 bitwise_and 交换,同时使用建议的 a.any() 和 a.all() 方法,我仍然得到相同的 ValueError。

y_valid = [True, False, True, False, False, True]
y_pred = [False, False, True, True, False, False]

for i in (y_valid, y_pred):
    CM = []
    if (y_valid[i] == False) & (y_pred[i] == False):
        CM == 0
    elif (y_valid[i] == False) & (y_pred[i] == True):
        CM == 1
    elif (y_valid[i] == True) & (y_pred[i] == False):
        CM == 2
    elif (y_valid[i] == True) & (y_pred[i] == True):
        CM == 3

我希望得到一个包含 0-3 数字的数组 CM

我的输出:

ValueError                                Traceback (most recent call last)
<ipython-input-107-259ac7895185> in <module>
      1 for i in (y_valid, y_pred):
      2     CM = []
----> 3     if (y_valid[i] == False) & (y_pred[i] == False):
      4         CM == 0
      5     elif (y_valid[i] == False) & (y_pred[i] == True):

ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all()

【问题讨论】:

  • 我认为上面的代码存在一些问题:(1)for循环i - 它的预期值是多少?据我所知,i 是一个列表! (2)CM == 3:你的意思是CM.append(3)还是CM = 3? (3) Python bool 比较并不是真正必要的(if y_value[i] and not y_pred[i]) 应该可以工作,最后 (4) 你的意思是and 而不是&amp;
  • 对不起,我是新手。我真的不知道 CM == 3 或 CM.append(3) 之间的区别。我想将整数值分配给给 if 语句的 CM 数组。我尝试了带有 append 的代码并且它有效,但我只收到了 CM 中的一个值,而不是与 y_valid 和 y_pred 相同的长度。
  • 不用担心@Changer,我们都从某个地方开始:)。根据您的评论,我发布了一个答案,它将在 CM 中返回一个数组/列表。解释了我在 cmets 中的变化

标签: python for-loop if-statement valueerror


【解决方案1】:

如果我理解正确,您需要以下内容:

y_valid = [True, False, True, False, False, True]
y_pred = [False, False, True, True, False, False]

# Move this out of the loop so you do not reset it every time!
CM = []

# To make i integer (as required for it to be list index) 
# use range and len.
for i in range(len(y_valid)):
    # Dropping comparisons with True/False values since 
    # the following would be the same. Also note that `&` is 
    # a bitwise operator in python while `and` is boolean
    if not y_valid[i] and not y_pred[i]:
        # In every iteration we are now appending to the same CM list
        CM.append(0)
    elif not y_valid[i] and y_pred[i]:
        CM.append(1)
    elif y_valid[i] and not y_pred[i]:
        CM.append(2)
    elif y_valid[i] and y_pred[i]:
        CM.append(3)

print(CM)

输出是:

$ python /tmp/test.py 
[2, 0, 3, 1, 0, 2]

检查代码中的 cmets 以了解我对原始代码所做的更改。如果您有任何问题,请告诉我

【讨论】:

  • 非常感谢这一切都很好!很好的解释:)
【解决方案2】:

您可以使用布尔值可以转换为整数的事实:

not y_valid[i] and not y_pred[i] => int(y_valid[i]) == 0 and int(y_pred[i]) == 0 => 2*y_valid[i] + y_pred[i] == 0
not y_valid[i] and y_pred[i]     => int(y_valid[i]) == 0 and int(y_pred[i]) == 1 => 2*y_valid[i] + y_pred[i] == 1
y_valid[i] and not y_pred[i]     => int(y_valid[i]) == 1 and int(y_pred[i]) == 0 => 2*y_valid[i] + y_pred[i] == 2
y_valid[i] and y_pred[i]         => int(y_valid[i]) == 1 and int(y_pred[i]) == 1 => 2*y_valid[i] + y_pred[i] == 3

并使用列表推导式创建CM

>>> y_valid = [True, False, True, False, False, True]
>>> y_pred = [False, False, True, True, False, False]

>>> [2*y_v+y_p for y_v, y_p in zip(y_valid, y_pred)]
[2, 0, 3, 1, 0, 2]

(注意:zip 将占用每个y_valid[i], y_pred[i]i in range(min(len(y_valid), len(y_pred)))。

【讨论】:

    【解决方案3】:

    您的错误在循环中。您正在迭代一个真值陈述列表,这就是为什么您会收到与使用 any()all() 相关的错误,因为您需要定义是否要查看是否有 any() True 值或 all() True条件中的值。

    y_valid = [True, False, True, False, False, True]
    y_pred = [False, False, True, True, False, False]
    
    for i in (y_valid, y_pred):
        print(i)
        break
    
    [Out]: [True, False, True, False, False, True]
    

    执行此操作的更快方法是压缩数组中的值。 压缩这些值会创建一个要迭代的元组列表:

    y_valid = [True, False, True, False, False, True]
    y_pred = [False, False, True, True, False, False]
    
    print(list(zip(y_valid, y_pred)))
    
    [Out]: [(True, False), (False, False), (True, True), (False, True), (False, False), (True, False)]
    

    最后,您可能希望存储列表中每个点的值。这种情况下,需要修改赋值如下:

    CM = []
    for valid, pred in zip(y_valid, y_pred):
        if not valid and not pred:
            CM.append(0)
        elif not valid and pred:
            CM.append(1)
        elif valid and not pred:
            CM.append(2)
        else:
            CM.append(3)
    

    【讨论】:

    • 我在第 3 行遇到语法错误(如果无效且未预置:)
    • true - 你需要使用and
    【解决方案4】:

    考虑到两个列表的长度相同。

    y_valid = [True, False, True, False, False, True]
    y_pred = [False, False, True, True, False, False]
    
    CM = -1
    for i in range(len(y_pred)):
        if (y_valid[i] == False) and (y_pred[i] == False):
            CM == 0
        elif (y_valid[i] == False) and (y_pred[i] == True):
            CM == 1
        elif (y_valid[i] == True) and (y_pred[i] == False):
            CM == 2
        elif (y_valid[i] == True) and (y_pred[i] == True):
            CM == 3
    

    不过,python 中有更好的方法来遍历列表或多个列表。

    您的代码基本上遍历tuple
    (y_valid, y_pred) 基本上是tuple。您的代码正在遍历每个列表的元组。

    for i in (y_valid, y_pred):
        print(i)
    

    输出:

    [True, False, True, False, False, True]
    [False, False, True, True, False, False]
    

    遍历多个列表的pythonic方法是zip它们。

    y_valid = [True, False, True, False, False, True]
    y_pred = [False, False, True, True, False, False]
    
    CM = -1
    for y_valid_i, y_pred_i in zip(y_valid, y_pred):
        if not y_valid_i and not y_pred_i:
            CM == 0
        elif not y_valid_i and y_pred_i:
            CM == 1
        elif y_valid_i and not y_pred_i:
            CM == 2
        elif y_valid_i and y_pred_i:
            CM == 3
    

    但是,您使用变量CM 的方式可能会遇到更多错误。

    【讨论】:

    • 我将您的代码复制到新文件中,但它只返回 CM = [ ]
    • 在 for 循环外声明 CM = -1。我已经更新了我的答案。希望这对你有用。 @Changer
    • 这只是返回 CM = -1。以任何方式感谢您的努力! Urban 为我提供了正确的答案。
    【解决方案5】:
    y_valid = [True, False, True, False, False, True]
    y_pred = [False, False, True, True, False, False]
    
    for i in (y_valid, y_pred):
      print(i)
    

    返回

    [True, False, True, False, False, True]
    [False, False, True, True, False, False]
    

    所以 python 将(y_valid, y_pred) 视为一个元组。 试试:

    for i in range(len(y_valid)):
        # Code comes here
    

    for i in range(len(y_pred)):
        # Code comes here
    

    【讨论】:

    • 这是tuple 而不是generator
    • 抱歉,我会解决的。
    • 感谢您的帮助,该解决方案对我有所帮助,但只解决了一半的问题。无论如何,Urban 为我提供了完整的解决方案。感谢您的努力!
    猜你喜欢
    • 2012-06-04
    • 2020-11-29
    • 2015-08-24
    • 2021-02-17
    • 2021-05-23
    • 1970-01-01
    • 2013-08-09
    • 1970-01-01
    • 2023-03-15
    相关资源
    最近更新 更多