python - 修改函数内部的掩码数组的一部分

时间:2016-08-25 14:09:06

标签: python arrays numpy masked-array

我需要在函数内修改一部分掩码数组,例如:

import numpy.ma as ma

arr_2d = ma.masked_all((5,5))
arr_3d = ma.masked_all((5,5,5))
arr_3d[0,1] = 5

def func1(arr, val):
    arr[:] = val

看起来很简单但是......

>>> func1(arr_3d[0], 1)
>>> arr_3d[0]
masked_array(data =
 [[-- -- -- -- --]
 [1.0 1.0 1.0 1.0 1.0]
 [-- -- -- -- --]
 [-- -- -- -- --]
 [-- -- -- -- --]],
             mask =
 [[ True  True  True  True  True]
 [False False False False False]
 [ True  True  True  True  True]
 [ True  True  True  True  True]
 [ True  True  True  True  True]],
       fill_value = 1e+20)

它似乎与共享掩码始终设置在数组的一个片上,以便将掩码作为副本传递给函数

我希望除了明确传递掩码,返回数据副本或传递数据之外,还有某种方法可以修复或绕过它。 带索引的较大数组。

1 个答案:

答案 0 :(得分:0)

最近numpy中的警告是:

In [738]: func1(A[1],1)
/usr/local/bin/ipython3:2: MaskedArrayFutureWarning: setting an item on 
a masked array which has a shared mask will not copy the mask and also 
change the original mask array in the future.
Check the NumPy 1.11 release notes for more information.

http://docs.scipy.org/doc/numpy/release.html#assigning-to-slices-views-of-maskedarray

  

目前,一个掩码数组的片段包含原始数据的视图和掩码的写时复制视图。因此,对切片掩码的任何更改都将导致生成原始掩码的副本,并且更改新掩码而不是原始掩码。

在此操作之后,A的第1行仍然被屏蔽,但A[,:]。data`已被更改。

In [757]: B=np.ma.masked_all((5))
...
In [759]: B[0]=5     # direct __setitem__ change to B
In [760]: B
Out[760]: 
masked_array(data = [5.0 -- -- -- --],
             mask = [False  True  True  True  True],
       fill_value = 1e+20)
In [761]: func1(B[3:],1)
/usr/local/bin/ipython3:2: MaskedArrayFutureWarning: ....

In [762]: B      # no change to mask
Out[762]: 
masked_array(data = [5.0 -- -- -- --],
             mask = [False  True  True  True  True],
       fill_value = 1e+20)
In [763]: B.data      # but data is changed
Out[763]: array([ 5.,  0.,  0.,  1.,  1.])

A[1,:]=1直接使用屏蔽的__setitem__,并且可以全权负责设置datamask。在您的函数中A是原始视图,通过A.__getitem__调用获得。显然,开发人员担心这个视图掩码的更改是否会影响原始掩码。

我们可能需要看看开发人员的讨论;警告表明最近发生了一些变化。

============

问题不是关于在功能中的使用,而是关于视图

In [764]: B1=B[3:]
In [765]: B1[:]=2
/usr/local/bin/ipython3:1: MaskedArrayFutureWarning:...
In [766]: B
Out[766]: 
masked_array(data = [5.0 -- -- -- --],
             mask = [False  True  True  True  True],
       fill_value = 1e+20)
In [767]: B.data
Out[767]: array([ 5.,  0.,  0.,  2.,  2.])

警告描述了现在发生的事情,可能还有一段时间。它说这种做法会改变。

根据更改说明建议:

In [785]: B1=B[3:]
In [787]: B1._sharedmask
Out[787]: True
In [790]: B1._sharedmask=False
In [791]: B1[:]=4
In [792]: B1
Out[792]: 
masked_array(data = [4.0 4.0],
             mask = [False False],
       fill_value = 1e+20)
In [793]: B     # mask has been changed along with data
Out[793]: 
masked_array(data = [5.0 -- -- 4.0 4.0],
             mask = [False  True  True False False],
       fill_value = 1e+20)

如此改变

 def func1(arr,val):
     arr._sharedmask=False
     arr[:]=val

将停止警告,并修改原始数组的掩码。