2015-12-01 86 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

相关问题