开发者

Numpy masked array modification

开发者 https://www.devze.com 2022-12-21 06:24 出处:网络
Currently I have a code that checks if given element in array is equal = 0 and if so then set the value to \'level\' value (temp_board is 2D numpy array, indices_to_watch contains 2D coordinates that

Currently I have a code that checks if given element in array is equal = 0 and if so then set the value to 'level' value (temp_board is 2D numpy array, indices_to_watch contains 2D coordinates that should be watched for zeros).

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

I would like to convert this to a more numpy-l开发者_JAVA技巧ike approach (remove the for and use only numpy functions) to speed this up. Here's what I tried:

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

But unfortunately masked array when doing put() wants to have 1D dimensions (totally strange!), is there some other way of updating array elements that are equal to 0 and have concrete indices?

Or maybe using masked arrays is not the way to go?


Assuming that it is not very inefficient to find out where temp_board is 0, you can do what you want like this:

# 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

If you can't do the above, then here's a way, but I am not sure if it's the most Pythonic:

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

First, convert to a numpy array:

indices_to_watch = numpy.array(indices_to_watch)

Then, make it indexable:

index = zip(*indices_to_watch)

Then, test the condition:

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

Then, figure out the actual indices to set:

final_index = zip(*indices_to_watch[indices_to_set])

Finally, set the values:

temp_board[final_index] = level


I'm not sure i follow all of the detail in your question. If i understood it correctly, then it seems like this is straightforward Numpy indexing. The code below checks the array (A) for zeros, and where it finds them, it replaces them with 'level'.

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


You should try something along those lines:

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

精彩评论

暂无评论...
验证码 换一张
取 消