2013-10-04 44 views
2

在修改掩碼數組中的數據時,我並不期待以下行爲。似乎有些值可以用[]操作數修改,但不是全部。但是,如果您訪問其數據屬性,那麼您可以修改全部。只有在元組中的單元格的掩碼中存在True值時纔會發生這種情況(與掩碼數組相關的所有操作似乎都可以正常工作)。無法修改掩碼數組中的數據。 arr [i] vs arr.data [i]

任何人都可以解釋爲什麼?

>>> import numpy as np 
>>> import numpy.ma as ma 
>>> arr = ma.ones(nrows, dtype=[('c1', np.int),('c2', np.int)]) 
>>> arr.mask[1][0] = True 
>>> arr[1][1] = 3 
>>> arr[0][0] = 4 
>>> arr 
masked_array(data = [(4, 1) (--, 1) (1, 1)], 
     mask = [(False, False) (True, False) (False, False)], 
    fill_value = (999999, 999999), 
     dtype = [('c1', '<i8'), ('c2', '<i8')]) 

>>> arr.data[1][1]=5 
>>> arr 
masked_array(data = [(4, 1) (--, 5) (1, 1)], 
     mask = [(False, False) (True, False) (False, False)], 
    fill_value = (999999, 999999), 
     dtype = [('c1', '<i8'), ('c2', '<i8')]) 

回答

3

我相信這是一個錯誤。這是發生了什麼事。

當使用(其工作方式所需的)

arr.data[1][1]=5 

功能_get_data()使用並返回底層nparray的簡單視圖。

當您使用(工作不正確地)

arr[1][1]=5 

功能__getitme__()使用。首先,它進入並嘗試抓取第1行。它檢測到該行上的一個項目被遮罩,並返回該行的遮罩副本(而不是視圖到數組)。根本問題是與該行ma \ core.py(目前在github的版本線2996)的:

dout = mvoid(dout, mask=mask, hardmask=self._hardmask) 

的mvoid函數返回第1行(其中包括的值[1][0]掩模)的副本而不是第1行的視圖。然後處理列索引時,它將更改到副本而不是視圖。

爲什麼在不包含掩碼的行上工作的原因是該視圖被返回而不是movid()拷貝。

這整個副本與查看的東西是一個非常經典的numpy陷阱。爲了公平地對待開發者,給定__getitem__()必須如何爲掩碼數組運行(即,它在讀取值時必須返回一個掩碼副本),我不知道他們如何解決它。但是,看看有沒有人比我有一個想法更加靈活,可能值得一個錯誤票。

2

吸氣arr[i][j]未在documentation列爲訪問數據以適當的方式。它提供了4種其他方式,而我嘗試了3種:

>>> import numpy as np 
>>> arr = np.ma.ones(3, dtype=[('c1', np.int),('c2', np.int)]) 
>>> arr.mask[0][1] = arr.mask[1][1] = arr.mask[2][1]= True 
>>> arr.data[0][0] = 2    # data attribute 
>>> np.ma.getdata(arr)[1][0] = 3 # ma.getdata function 
>>> arr.__array__()[2][0] = 4  # __array__() method 
>>> print(arr) 
[(2, --) (3, --) (4, --)] 
相關問題