2015-12-01 84 views
4

我有兩個numpy蒙面數組,我想合併。我使用下面的代碼:合併兩個numpy蒙面數組的有效方法

import numpy as np 

a = np.zeros((10000, 10000), dtype=np.int16) 
a[:5000, :5000] = 1 
am = np.ma.masked_equal(a, 0) 

b = np.zeros((10000, 10000), dtype=np.int16) 
b[2500:7500, 2500:7500] = 2 
bm = np.ma.masked_equal(b, 0) 

arr = np.ma.array(np.dstack((am, bm)), mask=np.dstack((am.mask, bm.mask))) 
arr = np.prod(arr, axis=2) 
plt.imshow(arr) 

Plot of the resulting merged array

的問題是,np.prod()操作非常慢(4秒我的電腦)。有沒有一種更有效的方式獲得合併數組?

+0

什麼是毫無遮攔的速度? – hpaulj

+1

在你的真實數據中,數組中的數字總是像這樣的常量?你實際上是否需要乘以數字,還是僅僅是你真正關心的口罩? –

+0

我打算用這個代表圖像的數組。理想情況下,我想保留原始數組的值(我知道我的代碼不會保留這些值,因爲它們會在交集中相乘)... – MonkeyButter

回答

2

而不是使用dstack()prod()你的最後兩行,試試這個:

arr = np.ma.array(am.filled(1) * bm.filled(1), mask=(am.mask * bm.mask)) 

現在你不需要prod()可言的,你完全避免分配的3D陣列。

+0

此建議的效率提高了一個數量級!唯一的問題是數組bm不保留它的值。 bm乘以相交區域內的am值並在其外部得到0值。 – MonkeyButter

+0

@MonkeyButter:這很奇怪,不是嗎?我已經更新了我的答案,以便在乘法過程中添加「填充(1)」來解決該問題。請現在試試。 –

1

受到接受的答案的啓發,我找到了一種合併蒙版數組的簡單方法。它可以在掩碼上進行一些邏輯操作,並簡單地添加0填充的數組。

import numpy as np 

a = np.zeros((1000, 1000), dtype=np.int16) 
a[:500, :500] = 2 
am = np.ma.masked_equal(a, 0) 

b = np.zeros((1000, 1000), dtype=np.int16) 
b[250:750, 250:750] = 3 
bm = np.ma.masked_equal(b, 0) 

c = np.zeros((1000, 1000), dtype=np.int16) 
c[500:1000, 500:1000] = 5 
cm = np.ma.masked_equal(c, 0) 

bm.mask = np.logical_or(np.logical_and(am.mask, bm.mask), np.logical_not(am.mask)) 
am = np.ma.array(am.filled(0) + bm.filled(0), mask=(am.mask * bm.mask)) 

cm.mask = np.logical_or(np.logical_and(am.mask, cm.mask), np.logical_not(am.mask)) 
am = np.ma.array(am.filled(0) + cm.filled(0), mask=(am.mask * cm.mask)) 

plt.imshow(am) 

Merging three arrays

我希望有人發現這是很有幫助的某個時候。掩蓋的數組似乎不是非常有效的。所以,如果有人發現一個合併數組的替代品,我很樂意知道。

更新:基於@morningsun評論此實現30%的速度更快,更簡單:

import numpy as np 

a = np.zeros((1000, 1000), dtype=np.int16) 
a[:500, :500] = 2 
am = np.ma.masked_equal(a, 0) 

b = np.zeros((1000, 1000), dtype=np.int16) 
b[250:750, 250:750] = 3 
bm = np.ma.masked_equal(b, 0) 

c = np.zeros((1000, 1000), dtype=np.int16) 
c[500:1000, 500:1000] = 5 
cm = np.ma.masked_equal(c, 0) 

am[am.mask] = bm[am.mask] 
am[am.mask] = cm[am.mask] 

plt.imshow(am) 
+2

我認爲這更簡單,也更快一點:'am [am.mask] = bm [am.mask]; am [am.mask] = cm [am.mask]' –

+0

@morningsun這太棒了,太簡單了!附加的數組甚至不需要被屏蔽的數組。這比任何其他方法都快。非常感謝你! – MonkeyButter

相關問題