亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

將 += 與 numpy.array 和 numpy.ma.array 一起使用的奇怪行為

將 += 與 numpy.array 和 numpy.ma.array 一起使用的奇怪行為

烙印99 2023-06-13 15:11:02
誰能向我解釋以下結果?我知道這不是通常執行此操作的方式,但我發現此結果很奇怪。import numpy as npa = np.ma.masked_where(np.arange(20)>10,np.arange(20))b = np.ma.masked_where(np.arange(20)>-1,np.arange(20))c = np.zeros(a.shape)d = np.zeros(a.shape)c[~a.mask] += b[~a.mask]print(b[~a.mask])#masked_array(data=[--, --, --, --, --, --, --, --,--, --, --],#             mask=[ True,  True,  True,  True,  True,  True,  True,  True, True,  True,  True],#       fill_value=999999,#            dtype=int64)print(c)#[ 0.  1.  2.  3.  4.  5.  6.  7.  8.  9. 10.  0.  0.  0.  0. 0.  0.  0.  0.  0.]d[~a.mask] = d[~a.mask] + b[~a.mask]print(d)#[0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0.]我預計c不會改變,但我想這里發生了一些與內存中的對象相關的事情。此外,+=保留原始對象,同時=創建+一個新的d.我只是不太明白添加到c.
查看完整描述

1 回答

?
慕娘9325324

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被退回。


查看完整回答
反對 回復 2023-06-13
  • 1 回答
  • 0 關注
  • 136 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號