有效地索引 2D 数组中的位置列表



这个函数需要一些tictactoe板并返回哪些动作是合法的尝试(-1表示"O",1表示"X",0表示空白(

def legal_locations(boards, moves):
legal_idxs, legal_locs = [], []
illegal_idxs, illegal_locs = [], []
for i, j in enumerate(moves):
# The middle index here is 0 because the locations > 0 are reserved for historical states.
# We only want to examine the current board state.
if boards[i][0][j]:  # This location is occupied
illegal_idxs.append(i)
illegal_locs.append(j)
else:  # unoccupied
legal_idxs.append(i)
legal_locs.append(j)
return (legal_idxs, legal_locs), (illegal_idxs, illegal_locs)

它工作正常,但"板"只是一个矩形 numpy 数组,而"移动"是一个列表。我认为必须有一种更快的方法来使用 numpy 完成此操作。有什么想法吗?

如果不能提高效率 - 很高兴知道这个问题会让它难以优化。

编辑:

boards =
array([[[ 0,  1,  0, -1,  0,  0,  0, -1,  0],
[ 0,  1,  0,  0,  0,  0,  0, -1,  0],
[ 0,  0,  0,  0,  0,  0,  0, -1,  0],
[ 0,  0,  0,  0,  0,  0,  0,  0,  0]],
[[ 0,  0,  0,  1, -1,  0,  0,  0, -1],
[ 0,  0,  0,  1, -1,  0,  0,  0,  0],
[ 0,  0,  0,  0, -1,  0,  0,  0,  0],
[ 0,  0,  0,  0,  0,  0,  0,  0,  0]]])

此棋盘数组显示两个游戏,每个游戏有 4 个历史状态。

moves =
[2, 8]

此移动数组显示两个索引。 因此,感兴趣的位置是:

boards[0][0][2]
boards[1][0][8]

所以在这个例子中,我们将从我们的 fxn 获得以下返回:

([0], [2]), ([1], [8])

编辑2:一个更核心的例子:

我想@AlexanderCécile部分问题是我不知道如何使用列表作为索引。例如,我不知道如何减少这个循环......

for i in range(legal.shape[0]):
legal[i, 0, index_list[i]] = -1

其中 len(index_list( == len(legal(

如果我能做到这一点,那么其他一切都应该使用 np.nonzero 卡入到位

将数组强制转换为bool,然后使用np.where生成对应于True值的索引(~运算符将反转强制转换数组(。对于单板:

array = np.array([[1, 0, 0], [-1, 1, 0], [1, -1, -1]])
mask = array.astype(bool)
illegal_row, illegal_col = np.where(mask)
legal_row, legal_col = np.where(~mask)

这可以通过运行领先索引扩展到多个板。

最新更新