将numpy数组添加到堆队列

时间:2017-02-14 21:45:14

标签: python arrays numpy heap

有人可以解释为什么以下代码导致ValueError?

import heapq
import numpy as np

a = np.ones((2, 2), dtype=int)

states = []
heapq.heappush(states, (0, a))
heapq.heappush(states, (0, a.copy()))

错误消息是:

Traceback (most recent call last):
  File "x.py", line 8, in <module>
    heapq.heappush(states, (0, a.copy()))
ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all()

在没有将a.copy()添加到堆的情况下运行它可以正常工作,第二个/后续的由于某种原因是一个问题。我确实理解,[True, False, True]数组存在一个未知真值的方面,并且无法从中确定单个TrueFalse,但为什么呢? heapq需要这样做吗?特别是只在第二种情况下?

1 个答案:

答案 0 :(得分:4)

TL; DR:因为如果numpy数组包含多个元素,则不能将其转换为布尔值。

关于堆的一些信息:

Heaps&#34; order&#34;他们的内容(因此项目必须实现<,但这是一个实现细节)。

然而,您可以通过为项目创建heap来将项目插入tuple,其中第一个元素是某个值,第二个元素是数组。

比较元组首先检查第一项是否相等,如果是,它检查第二项是否相等,等等直到它们不相等,那么它将检查它是否更小(当操作是<)或更高(>)。但是元组是用C实现的,而==检查有点与Python中的不同。它使用PyObject_RichCompareBool。特别是&#34;注意&#34;这里很重要

  

如果o1o2是同一个对象,则PyObject_RichCompareBool()将始终为Py_EQ返回1,为Py_NE返回0。

现在让我们去numpy数组:

如果numpy.array包含多个项目,则无法将bool转换为>>> arr = np.array([1,2,3]) >>> bool(arr) ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all()

if

>>> if arr: pass ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all() 检查隐式将条件转换为布尔值:

>>> arr > arr
array([False, False], dtype=bool)
>>> arr == arr
array([ True,  True], dtype=bool)

即使比较了numpy-arrays,它们仍然是numpy数组:

==

因此,无法使用>>> if arr == arr: pass ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all()

评估这些内容
heapq

因此,您无法将具有多个元素的numpy数组转换为布尔值!然而现在有了一个有趣的部分:PyObject_RichCompareBool() - 模块使用>>> arr is arr True >>> arr is arr.copy() False ,因此它可以检查两个数组是否相等,但当且仅当这些数组相同时才会生效!

这就是为什么它适用于多次传递的相同数组,但是当你复制它时会失败:

{{1}}