[Numpy-discussion] mapping a function to a masked array

Pierre GM pgmdevlist at gmail.com
Wed Jan 12 07:04:02 EST 2011


On Jan 12, 2011, at 12:45 PM, Ben Elliston wrote:

> I have a masked array of values that I would like to transform through
> a user-defined function.  Naturally, I want to ignore any values that
> are masked in the initial array.
> 
> The user-defined function examines other points around the value in
> question, so I need to use ndenumerate (or similar) to get the array
> index as I iterate over the array.

Can your function accept arrays as input ? 

> 
> So, I have two questions: how to make this run without looping in
> Python, and how to avoid masked values.  Here is the clunky solution I
> have so far:
> 
>    result = ma.copy (data)
>    for i, val in ndenumerate (data):
>        if not data.mask[i]:
> 	    result[i] = myfunc (data, i, val)

`result` doesn't have to be a masked array, right ?

result = np.empty_like(data)
ndata = data.data
for (i, (v, m)) in enumerate(zip(ndata, data.mask)):
	if not m:
		result[i] = myfunc(ndata, i, v)

The main point is to avoid looping on the masked array itself. Instead, you loop on the `data` and `mask` attributes , that are regular ndarrays only. Should be far more efficient that way.
Same thing for myfunc: don't call it on the masked array, just on the data part.

About looping: well, if you can vectorize your function, you may avoid the loop. You may also wanna try a list comprehension:
>>> result = [myfunc(ndata,i,v) for (i,(v,m)) in enumerate(zip(ndata,data.mask)) if not m]
and retransform result to a ndarray afterwards. Or use fromiterator ?

Let me know how it goes

Cheers
P.









More information about the NumPy-Discussion mailing list