np.where(条件为None)不等于np.where(条件== None)

Phi*_*ipp 5 python numpy

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

背景:我正在编写“四人连线”游戏。此insert_chip()方法访问变量self.board是我的个人dtype的8x8 np数组Chip。如果chip的条目中没有self.board,则值为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
Run Code Online (Sandbox Code Playgroud)

Wil*_*sem 6

由于某种原因,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))
Run Code Online (Sandbox Code Playgroud)


hpa*_*ulj 5

制作一个对象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)
Run Code Online (Sandbox Code Playgroud)

is None测试:

In [41]: arr is None
Out[41]: False
Run Code Online (Sandbox Code Playgroud)

==测试。

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]))
Run Code Online (Sandbox Code Playgroud)

对象数组中比较测试的传播已经发生了一些变化。来自最新的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
Run Code Online (Sandbox Code Playgroud)