Numpy掩膜数组修改

1 投票
3 回答
2775 浏览
提问于 2025-04-15 19:32

目前我有一段代码,它会检查数组中的某个元素是否等于0,如果是的话,就把这个值设置为'level'的值(temp_board是一个二维的numpy数组,indices_to_watch包含需要关注的二维坐标,这些坐标对应的值可能是0)。

    indices_to_watch = [(0,1), (1,2)]
    for index in indices_to_watch:
        if temp_board[index] == 0:
            temp_board[index] = level

我想把这个代码改成更符合numpy的方式,也就是去掉for循环,只用numpy的函数来加快速度。以下是我尝试的代码:

    masked = np.ma.array(temp_board, mask=(a!=0), hard_mask=True)
    masked.put(indices_to_watch, level)

但是不幸的是,当我使用put()函数处理掩码数组时,它要求数组是1维的(这真是奇怪!),有没有其他方法可以更新那些等于0并且有具体索引的数组元素呢?

或者说,使用掩码数组真的不是个好主意吗?

3 个回答

0

你可以试试下面这样的做法:

temp_board[temp_board[field_list] == 0] = level
1

我不太明白你问题里的所有细节。如果我理解得没错的话,这看起来就是简单的Numpy索引。下面的代码会检查数组(A)中的零,然后把找到的零替换成'level'。

import numpy as NP
A = NP.random.randint(0, 10, 20).reshape(5, 4) 
level = 999
ndx = A==0
A[ndx] = level
1

假设找到temp_board中值为0的位置并不是特别费劲,你可以像这样做你想做的事情:

# First figure out where the array is zero
zindex = numpy.where(temp_board == 0)
# Make a set of tuples out of it
zindex = set(zip(*zindex))
# Make a set of tuples from indices_to_watch too
indices_to_watch = set([(0,1), (1,2)])
# Find the intersection.  These are the indices that need to be set
indices_to_set = indices_to_watch & zindex
# Set the value
temp_board[zip(*indices_to_set)] = level

如果你不能这样做,那这里有另外一种方法,不过我不确定这是不是最符合Python风格的:

indices_to_watch = [(0,1), (1,2)]

首先,把数据转换成numpy数组:

indices_to_watch = numpy.array(indices_to_watch)

然后,让它可以被索引:

index = zip(*indices_to_watch)

接着,测试条件:

indices_to_set = numpy.where(temp_board[index] == 0)

然后,找出需要设置的实际索引:

final_index = zip(*indices_to_watch[indices_to_set])

最后,设置这些值:

temp_board[final_index] = level

撰写回答