合并两个numpy蒙版数组的有效方法

时间:2015-12-01 05:37:14

标签: python numpy multidimensional-array mask array-merge

我想要合并两个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秒)。是否有另一种以更有效的方式获得合并数组的方法?

3 个答案:

答案 0 :(得分:2)

使用dstack()prod()代替最后两行,请尝试以下操作:

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

现在你根本不需要prod(),而且你完全避免分配3D数组。

答案 1 :(得分:2)

我采用了另一种方法,该方法可能不是特别有效,但是相当容易扩展和实施。

(我知道我要回答的问题已经存在了3年多了,但功能已经很长时间了,但请耐心等待)

numpy中的np.where函数有两个主要目的(有点奇怪),第一个是为您提供布尔数组的索引:

>>> import numpy as np

>>> a = np.arange(12).reshape(3, 4)
>>> a
array([[ 0,  1,  2,  3],
       [ 4,  5,  6,  7],
       [ 8,  9, 10, 11]])

>>> m = (a % 3 == 0)
>>> m
array([[ True, False, False,  True],
       [False, False,  True, False],
       [False,  True, False, False]], dtype=bool)

>>> row_ind, col_ind = np.where(m)
>>> row_ind
array([0, 0, 1, 2])
>>> col_ind
array([0, 3, 2, 1])

np.where函数的另一个目的是根据给定的布尔数组是否为True / False从两个数组中进行选择:

>>> np.where(m, a, np.zeros(a.shape))
array([[ 0.,  0.,  0.,  3.],
       [ 0.,  0.,  6.,  0.],
       [ 0.,  9.,  0.,  0.]])

结果是,还有一个numpy.ma.where可以处理掩码数组...

给出相同形状的蒙版数组列表,我的代码如下:

merged = masked_arrays[0]
for ma in masked_arrays[1:]:
    merged = np.ma.where(ma.mask, merged, ma)

正如我所说,这不是特别有效,但是肯定很容易实现。

HTH

答案 2 :(得分: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)