【问题标题】:np.where(condition is None) not equal to np.where(condition == None)np.where(condition is None) 不等于 np.where(condition == None)
【发布时间】:2018-11-16 20:15:50
【问题描述】:

我对 np.where() 函数感到困扰。 (在我的示例中为第 7 行)

背景:我正在编写游戏“Connect Four”。这个insert_chip() 方法访问变量self.board,它是我个人数据类型Chip 的一个8x8 np 数组。如果self.board的条目中没有chip,则值为None

由于某种原因,np.where(col_entries is None) 不返回 None 元素的索引。当我在条件中写入col_entries == None 时,为什么会收到不同的输出?不是None有引用权吗?

def insert_chip(self, chip, col):
    # slices the entries of the column into a new array
    col_entries = self.board[:, col:col+1]

    # checks for all unoccupied pos in this col (entries are None)
    # gives double array of indexes with the form (array([row_i, ...]), array([col_i, ...]))
    none_indexes = np.where(col_entries is None)

    # the pos where the chip will fall is the one with the highest index
    self.board[len(none_indexes[0]), col] = chip

【问题讨论】:

  • is 检查col_entries(所以你的矩阵本身)是否为None。所以这是总是 False.
  • This site 是检查python中is==之间区别的好地方。
  • 比较(col_entries is None)(col_entries==None)。测试先完成,然后传递给where。如果测试数组没有意义,那么where 结果也不会。
  • 无总是需要检查is。其他任何东西都不安全。
  • dtypeself.board 是什么? object 还是数字?具有数字 dtype 的数学更快,但它不能容纳 None 对象。而object dtype数组更像是一个列表,或者如果是2d,则是一个列表的列表。

标签: python numpy


【解决方案1】:

由于某种原因,np.where(col_entries is None) 不会返回 None 元素的索引。

is 运算符检查两个操作数是否指向同一个对象。所以这里它检查col_entries(矩阵)是否为None,因此执行“广播”来检查矩阵中的某些元素是否引用None

在 Python 中,可以重载某些运算符,如 <=== 等。Numpy 使用它来实现特定的运算符,这样就可以编写 some_matrix == 0 来生成布尔矩阵。 is 运算符不能 被重载,因此 Numpy(或任何其他库)可以控制它。 is 只是检查两个操作数是否引用同一个对象。

由于这里您的col_entries 指的是一个numpy 数组,所以它始终是False,因此np.where(col_entries is None) 将始终返回一个包含空数组的1 元组。

虽然没有那么多对象等于None,但依靠它仍然不是很安全。我们可以向量化is 操作符,比如:

from operator import is_

np.where(np.vectorize(is)(col_entries, None))

【讨论】:

  • 这个解释对我有帮助。那么应该改用== 吗?
【解决方案2】:

创建一个对象 dtype 数组:

In [37]: arr = np.zeros((3,3), object)
In [39]: arr[range(3),range(3)]=None
In [40]: arr
Out[40]: 
array([[None, 0, 0],
       [0, None, 0],
       [0, 0, None]], dtype=object)

is None 测试:

In [41]: arr is None
Out[41]: False

== 测试。

In [42]: arr == None
Out[42]: 
array([[ True, False, False],
       [False,  True, False],
       [False, False,  True]])
In [43]: np.where(arr == None)
Out[43]: (array([0, 1, 2]), array([0, 1, 2]))

对象数组中比较测试的传播已经发生了一些变化。来自最近的 release_notes:https://docs.scipy.org/doc/numpy-1.15.1/release.html#comparison-ufuncs-accept-dtype-object-overriding-the-default-bool


列表上的类似操作

In [44]: alist = [0,None,0]
In [45]: alist is None
Out[45]: False
In [46]: [i is None for i in alist]
Out[46]: [False, True, False]
In [48]: alist.index(None)
Out[48]: 1

【讨论】:

    猜你喜欢
    • 2020-03-04
    • 2021-01-17
    • 2018-11-29
    • 2019-08-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-11-29
    相关资源
    最近更新 更多