Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/280.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/xamarin/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 合并两个numpy屏蔽阵列的有效方法_Python_Numpy_Multidimensional Array_Mask_Array Merge - Fatal编程技术网

Python 合并两个numpy屏蔽阵列的有效方法

Python 合并两个numpy屏蔽阵列的有效方法,python,numpy,multidimensional-array,mask,array-merge,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) a

我有两个要合并的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)


问题是
np.prod()
操作非常慢(在我的计算机中为4秒)。有没有其他更有效的方法来获取合并数组?

使用
dstack()
prod()
代替最后两行,尝试以下方法:

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

现在您根本不需要
prod()
,并且可以避免完全分配3D阵列。

受公认答案的启发,我找到了一种合并遮罩阵列的简单方法。它可以在掩码上进行一些逻辑操作,并简单地添加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)

我希望有人会觉得这有帮助。但是屏蔽数组似乎不是很有效。所以,如果有人能找到合并数组的替代方案,我很乐意知道

更新:根据@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)

我采用了另一种可能不是特别有效的方法,但很容易扩展和实现

(我知道我在回答一个3年多的问题,这个问题的功能在numpy已经存在很长时间了,但请耐心听我说)

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

>>> 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.其中
函数的另一个目的是根据给定的布尔数组是否为真/假从两个数组中选择:

>>> 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

没有掩蔽的速度是多少?在你的真实数据中,数组中的数字真的总是这样的常数吗?你真的需要将数字相乘,还是仅仅是你真正关心的遮罩?我打算用它来表示图像的数组。理想情况下,我希望保留原始数组的值(我知道我的代码在交叉点相乘时也不会保留这些值)…这个建议效率高一个数量级!唯一的问题是数组bm不保留其值。bm在交叉区域内乘以am值,在交叉区域外得到0值。@MonkeyButter:嗯,这很奇怪,不是吗?我已经更新了我的答案,在乘法过程中添加
filled(1)
,以解决这个问题。请现在试试。我认为这更简单,也更快一些:
am[am.mask]=bm[am.mask];am[am.mask]=cm[am.mask]
@morningsun这太棒了,太简单了!附加的数组甚至不需要是掩码数组。这比任何其他方法都要快。非常感谢你!