2016-08-09 57 views
2

我想從壓縮的遮罩數組和對應的遮罩創建一個數組。它更容易用一個例子來說明這一點:反轉「numpy.ma.compressed」操作

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

現在我想創建相同的形狀,x,其中屏蔽值獲得一個標準值的數組(例如-1),其餘部分充滿了給定的數組。它應該是這樣的:

>>> z = decompress(y, mask=[[True,True],[False,False]], default=-1) 
>>> z 
array([[-1, -1], 
     [ 2, 3]]) 

的問題是:有沒有像「解壓縮」的任何方法,或者我需要編寫它自己?在Fortran中,這是通過「pack」和「unpack」方法完成的。 感謝您的任何建議。

回答

3

雖然我已經回答了一些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]) 

y有大約x除了值的子集的信息。注意:這是一維

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) 

我的猜測是,到de-compress我們需要一個empty屏蔽數組使用正確的dtype,shape和mask,並將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]]) 

或進行新的陣列

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]]) 

另一種方法是使規則陣列,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]]) 

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

https://github.com/numpy/numpy/blob/master/numpy/ma/core.py 
class _MaskedBinaryOperation: 

這個類是用來實現蒙面ufunc。它計算ufunc在有效的細胞(非掩碼),並返回具有有效的人新的掩蔽陣列,留下未改變的掩蔽值(從原始)

例如用一個簡單的屏蔽數組,+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]) 

_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) 

但蒙面日誌跳過遮蓋的條目:

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]) 

哎呀 - _MaskedUnaryOperation可能不是那麼有用。它以np.ma.getdata(z)的所有值評估ufunc,使用errstate上下文來阻止警告。然後使用掩碼將掩碼值複製到結果(np.copyto(result, d, where=m))。

+0

哇......這是一個巨大的信息負載! 「np.place」現在爲我做了詭計!非常感謝! – greeeeeeen