1 回答

TA貢獻1783條經驗 獲得超4個贊
我將從一個更簡單的示例開始,以便更好地理解:
b = np.ma.masked_where(np.arange(20)>-1,np.arange(20))
#b: [-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --]
#b.data: [ 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19]
c = np.zeros(b.shape)
#c: [0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0.]
d = np.zeros(b.shape)
#d: [0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0.]
c += b
#c: [ 0. 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19.]
d = d + b
#d: [-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --]
#d.data: [0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0.]
第一個操作c += b是就地操作。換句話說,它等效于c = type(c).__iadd__(c, b)which 根據 的類型進行加法c,這不是屏蔽數組,因此 的數據用作b未屏蔽的。
另一方面,d = d + b等同于d = np.MaskedArray.__add__(d, b)(更具體地說,由于屏蔽數組是 ndarray 的子類,它使用__radd__)并且不是就地賦值。這意味著它創建一個新對象并在添加時使用等式右側的更寬類型,因此將 d (這是一個未屏蔽的數組)轉換為屏蔽數組(因為它是一個屏蔽數組),因此加法使用b有效僅值(在本例中沒有值,因為所有元素都b被屏蔽且無效)。這會產生一個掩碼數組,其掩碼與數據保持不變時d相同。bd
這種行為差異不是 Numpy 特有的,也適用于 python 本身。OP 問題中提到的案例具有類似的行為,正如@alaniwi 在評論中提到的那樣,帶有掩碼的布爾索引a并不是該行為的基礎。使用a屏蔽b, ,c和的元素d只是限制對被屏蔽元素的賦值a(而不是數組的所有元素),僅此而已。
為了使事情更有趣,實際上更清晰,讓我們切換右側的b和的位置:d
e = np.zeros(b.shape)
#e: [0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0.]
e = b + e
#e: [-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --]
#e.data: [ 0. 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19.]
請注意,與 類似d = d + b,右側使用掩碼數組__add__函數,因此輸出是一個掩碼數組,但由于您要添加e到b(aka e = np.MaskedArray.__add__(b, e)),因此返回的掩碼數據b,而在 中d = d + b,您將添加b到d和數據d被退回。
添加回答
舉報