带有两个布尔数组的 For 循环 If 条件中的 ValueError

ValueError in For Loop's If Condition with two boolean arrays

我是 运行 一个带有 If 语句的 For 循环,其中包含两个布尔数组以创建一个新数组。

我已经尝试了所有可以在 Whosebug 上找到的解决方案,将 & 与 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()

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

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 的方式很可能会 运行 陷入更多错误。

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)

returns

[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

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

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)

如果我没理解错的话你想要的是:

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]

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

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

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