比较两个三维Numpy数组,并返回带索引的不匹配值,然后在没有循环的情况下重新创建它们



我目前正在处理一个问题,在一个需求中,我需要比较两个3d NumPy数组,并返回与其索引位置不匹配的值,然后重新创建相同的数组。目前,我能想到的唯一方法是在数组之间循环,以便在比较和稍后重新创建时获得值。问题在于规模,因为将有数百个阵列,循环会影响整个应用程序的延迟。如果有人能帮助我更好地利用NumPy比较,同时使用最小循环或无循环,我将不胜感激。下面是一个伪代码:

def compare_array(final_array_list):
base_array = None
i = 0
for array in final_array_list:
if i==0:
base_array =array[0]
else:
index = np.where(base_array != array)
#getting index like (array([0, 1]), array([1, 1]), array([2, 2]))
# to access all unmatched values I need to loop.Need to avoid loop here
i=i+1  

return [base_array, [unmatched value (8,10)and its index (array([0, 1]), array([1, 1]), array([2, 2])],..]    

# similarly recreate array1 back
def recreate_array(array_list):
# need to avoid looping while recreating array back
return list of array #i.e. [base_array, array_1]       
# creating dummy array    
base_array = np.array([[[1, 2, 3], [3, 4, 5]], [[5, 6, 7], [7, 8, 9]]])
array_1 = b = np.array([[[1, 2,3], [3, 4,8]], [[5, 6,7], [7, 8,10]]])
final_array_list = [base_array,array_1, ...... ]

#compare base_array with other arrays and get unmatched values (like 8,10 in array_1) and their index     
difff_array  = compare_array(final_array_list)
# recreate array1 from the base array after receiving unmatched value and its index value
recreate_array(difff_array)

我想这可能就是您想要的:

base_array = np.array([[[1, 2, 3], [3, 4, 5]], [[5, 6, 7], [7, 8, 9]]])
array_1 = b = np.array([[[1, 2,3], [3, 4,8]], [[5, 6,7], [7, 8,10]]])
match_mask = (base_array == array_1)
idx_unmatched = np.argwhere(~match_mask)
# idx_unmatched: 
#  array([[0, 1, 2],
#         [1, 1, 2]])
# values with associated with idx_unmatched:
values_unmatched = base_array[tuple(idx_unmatched.T)]
# values_unmatched: 
#  array([5, 9])

我不确定我是否理解你所说的"重新创建它们";(完全重新创建它们?为什么不使用数组本身呢?(。

不过,我可以帮你注意到,有很多函数都是用numpy向量化的,而且作为一般经验法则,除非G-d自己告诉你:(

例如:

  • 如果ab任何np.array(无论维度如何(,则简单的a == b将返回一个相同大小的numpy数组,并带有布尔值。Trues=在该坐标系中它们相等,否则为False。

  • 函数np.where(c)c转换为布尔np.array,并返回c为True的索引。

要澄清:在这里,我实例化了两个数组,其中b与a不同,值为-1:请注意a==b是什么,在末尾。

>>> a = np.random.randint(low=0, high=10, size=(4, 4))
>>> b = np.copy(a)
>>> b[2, 3] = -1
>>> b[0, 1] = -1
>>> b[1, 1] = -1
>>> a
array([[9, 9, 3, 4],
[8, 4, 6, 7],
[8, 4, 5, 5],
[1, 7, 2, 5]])
>>> b
array([[ 9, -1,  3,  4],
[ 8, -1,  6,  7],
[ 8,  4,  5, -1],
[ 1,  7,  2,  5]])
>>> a == b
array([[ True, False,  True,  True],
[ True, False,  True,  True],
[ True,  True,  True, False],
[ True,  True,  True,  True]])

现在函数np.where,它的输出有点棘手,但可以很容易地使用。这将返回两个大小相同的数组:第一个数组是行,第二个数组是给定数组为True的列。

>>> np.where(a == b)
(array([0, 0, 0, 1, 1, 1, 2, 2, 2, 3, 3, 3, 3], dtype=int64), array([0, 2, 3, 0, 2, 3, 0, 1, 2, 0, 1, 2, 3], dtype=int64))

现在你可以"修复";匹配ab数组,通过将其与a不同的bar索引的值切换为a的索引:

>>> b[np.where(a != b)]
array([-1, -1, -1])
>>> b[np.where(a != b)] = a[np.where(a != b)]
>>> np.all(a == b)
True

相关内容

最新更新