反转“ numpy.ma.compressed”操作

gre*_*een 3 python numpy masked-array

我想从压缩的蒙版数组和相应的蒙版创建一个数组。用一个例子更容易解释:

>>> x=np.ma.array(np.arange(4).reshape((2,2)), mask = [[True,True],[False,False]])
>>> y=x.compressed()
>>> y
array([ 2,  3])
Run Code Online (Sandbox Code Playgroud)

现在,我想创建一个与x形状相同的数组,其中被掩码的值获得一个标准值(例如-1),其余的用给定的数组填充。它应该像这样工作:

>>> z = decompress(y, mask=[[True,True],[False,False]], default=-1)
>>> z
array([[-1, -1],
       [ 2,  3]])
Run Code Online (Sandbox Code Playgroud)

问题是:是否有类似“解压缩”的方法,还是我需要自己编写代码?在Fortran中,这是通过“ pack”和“ unpack”方法完成的。感谢您的任何建议。

hpa*_*ulj 5

尽管我回答了许多ma问题,但我绝不是专家。但我会探讨这个问题

让我们概括一下数组:

In [934]: x=np.ma.array(np.arange(6).reshape((2,3)), mask = [[True,True,False],[False,False,True]])
In [935]: x
Out[935]: 
masked_array(data =
 [[-- -- 2]
 [3 4 --]],
             mask =
 [[ True  True False]
 [False False  True]],
       fill_value = 999999)
In [936]: y=x.compressed()
In [937]: y
Out[937]: array([2, 3, 4])
Run Code Online (Sandbox Code Playgroud)

yx除了值的子集外,没有其他信息。请注意这是1d

x存储在2门阵列(实际上这些属性的访问底层其值._data._mask属性):

In [938]: x.data
Out[938]: 
array([[0, 1, 2],
       [3, 4, 5]])
In [939]: x.mask
Out[939]: 
array([[ True,  True, False],
       [False, False,  True]], dtype=bool)
Run Code Online (Sandbox Code Playgroud)

我的猜测是,de-compress我们需要制作一个empty具有正确dtype,shape和mask 的masked数组,并将其值复制y到其中data。但是应将哪些值放入的蒙版元素中data

还是解决问题的另一种方法-是否可以将值从y后面复制到x

一种可能的解决方案是将新值复制到x[~x.mask]

In [957]: z=2*y
In [958]: z
Out[958]: array([4, 6, 8])
In [959]: x[~x.mask]=z
In [960]: x
Out[960]: 
masked_array(data =
 [[-- -- 4]
 [6 8 --]],
             mask =
 [[ True  True False]
 [False False  True]],
       fill_value = 999999)
In [961]: x.data
Out[961]: 
array([[0, 1, 4],
       [6, 8, 5]])
Run Code Online (Sandbox Code Playgroud)

或制作一个新的数组

In [975]: w=np.zeros_like(x)
In [976]: w[~w.mask]=y
In [977]: w
Out[977]: 
masked_array(data =
 [[-- -- 2]
 [3 4 --]],
             mask =
 [[ True  True False]
 [False False  True]],
       fill_value = 999999)
In [978]: w.data
Out[978]: 
array([[0, 0, 2],
       [3, 4, 0]])
Run Code Online (Sandbox Code Playgroud)

另一种方法是full用无效值制作一个规则数组,y像这样复制,然后将整个对象变成一个掩码数组。可能有一个带掩码的数组构造函数,可让您仅与掩码一起指定有效值。但是我必须为此深入研究文档。

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

np.place用于设置值的另一序列操作将执行此操作

In [1011]: w=np.empty_like(x)
In [1014]: np.place(w,w.mask,999)
In [1015]: np.place(w,~w.mask,[1,2,3])
In [1016]: w
Out[1016]: 
masked_array(data =
 [[-- -- 1]
 [2 3 --]],
             mask =
 [[ True  True False]
 [False False  True]],
       fill_value = 999999)
In [1017]: w.data
Out[1017]: 
array([[999, 999,   1],
       [  2,   3, 999]])
Run Code Online (Sandbox Code Playgroud)

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

看着

https://github.com/numpy/numpy/blob/master/numpy/ma/core.py 
class _MaskedBinaryOperation:
Run Code Online (Sandbox Code Playgroud)

此类用于实现masked ufunc。它评估ufuncat的有效单元格(非掩码),并返回带有有效数组的新掩码数组,而掩码值保持不变(与原始值相比)

例如,对于简单的掩码数组,+1不会更改掩码值。

In [1109]: z=np.ma.masked_equal([1,0,2],0)
In [1110]: z
Out[1110]: 
masked_array(data = [1 -- 2],
             mask = [False  True False],
       fill_value = 0)
In [1111]: z.data
Out[1111]: array([1, 0, 2])
In [1112]: z+1
Out[1112]: 
masked_array(data = [2 -- 3],
             mask = [False  True False],
       fill_value = 0)
In [1113]: _.data
Out[1113]: array([2, 0, 3])
In [1114]: z.compressed()+1
Out[1114]: array([2, 3])
Run Code Online (Sandbox Code Playgroud)

_MaskedUnaryOperation 可能更简单,因为它只需要使用1个蒙版数组即可。

例如,常规日志的掩码0值存在问题:

In [1115]: z.log()
...
/usr/local/bin/ipython3:1: RuntimeWarning: divide by zero encountered in log
  #!/usr/bin/python3
Out[1116]: 
masked_array(data = [0.0 -- 0.6931471805599453],
             mask = [False  True False],
       fill_value = 0)
Run Code Online (Sandbox Code Playgroud)

但是被屏蔽的日志会跳过被屏蔽的条目:

In [1117]: np.ma.log(z)
Out[1117]: 
masked_array(data = [0.0 -- 0.6931471805599453],
             mask = [False  True False],
       fill_value = 0)
In [1118]: _.data
Out[1118]: array([ 0.        ,  0.        ,  0.69314718])
Run Code Online (Sandbox Code Playgroud)

糟糕- _MaskedUnaryOperation可能没那么有用。它会评估ufunc所有值np.ma.getdata(z),并使用errstate上下文来阻止警告。然后,它使用掩码将掩码值复制到结果(np.copyto(result, d, where=m))。