首页 > 解决方案 > 如何让 np.where 仅返回 for 循环所在的位置?(Python)

问题描述

我创建了一个虚拟棋盘,其中 64 个空格形成为嵌套数组。我正在尝试遍历每个点并检查该点的值是否为零。我正在使用 np.where 来获取现场的索引,但最终 np.where 开始返回多个值,这会引发错误。我怎样才能让它只返回我当前所在位置的索引?

    while chessboard[result[0], result[1]] != 0:
    for row in chessboard:
        for spot in row:
            if spot == 0:
                location = np.where(chessboard == spot)
                print(location)
                for move in possible_moves:
                    if (location[0] + move[0]) < 0 or (location[1] + move[1]) < 0 or (location[0] + move[0]) > 7 or (location[1] + move[1]) > 7:
                        continue
                    else:
                        chessboard_updated[location[0] + move[0], location[1] + move[1]] = 0

    chessboard = chessboard_updated
    counter += 1

最终我得到了错误

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

因为

location

返回

(array([5, 6, 7], dtype=int32), array([1, 2, 0], dtype=int32))

它返回 5,6,7 而不仅仅是 1 个值

谢谢你。

标签: pythonnumpy

解决方案


总结评论。

In [102]: arr = np.random.randint(0,4,(5,5))                                                         
In [103]: arr                                                                                        
Out[103]: 
array([[1, 2, 1, 0, 2],
       [1, 2, 3, 0, 0],
       [3, 0, 1, 1, 1],
       [0, 0, 3, 3, 0],
       [1, 3, 2, 0, 1]])

np.where返回一个数组元组,告诉我们条件为真:

In [104]: np.nonzero(arr==0)                                                                         
Out[104]: (array([0, 1, 1, 2, 3, 3, 3, 4]), array([3, 3, 4, 1, 0, 1, 4, 3]))

该元组可以直接用于索引源数组:

In [105]: arr[_]                                                                                     
Out[105]: array([0, 0, 0, 0, 0, 0, 0, 0])

np.transpose我们可以使用(或)将该元组转换为二维数组argwhere

In [106]: np.argwhere(arr==0)                                                                        
Out[106]: 
array([[0, 3],
       [1, 3],
       [1, 4],
       [2, 1],
       [3, 0],
       [3, 1],
       [3, 4],
       [4, 3]])

但这不能直接用于索引数组。我们要么必须迭代,要么将列用作索引:

In [107]: [arr[tuple(ij)] for ij in _106]                                                               
Out[107]: [0, 0, 0, 0, 0, 0, 0, 0]
In [108]: arr[_106[0], _106[1]]                                                                      
Out[108]: array([2, 3])
In [109]: arr[_106[:,0], _106[:,1]]                                                                  
Out[109]: array([0, 0, 0, 0, 0, 0, 0, 0])

如果条件数组只有一个True,那么where元组将类似于:

(np.array([0]), np.array([4]))

两个大小为 1 的数组。

因为您找到了多个True点,所以您会收到歧义错误。

if (location[0] + move[0]) < 0 or (location[1] + move[1]) < 0 ...

location[0]是一个有多个值的数组。 (location[0] + move[0]) < 0然后是一个具有超过 1 个值的布尔数组。这不能在 Pythonifor上下文中使用,两者都只需要一个 True/False 值。


推荐阅读