如何比较多维两个NumPy数组并删除其中一个数组中的元素(如果元素也在另一个数组中

kpbwa7wx  于 2022-11-10  发布在  其他
关注(0)|答案(1)|浏览(236)

我有两个形状为(n,3,2)和(n,2)的数字数组。
我想从第一个数组中删除一个或多个元素(以便它的形状为(n-1)、3,2或(n-2)、3,2等)。如果这些也是第二个数组的元素。
做这样的事情最好的方法是什么?任何帮助都是非常感谢的。
比方说

array1 = 
[[[ 5.1  5. ]
  [ 6.2  4.4]
  [ 4.   6.3]]

 [[ 4.2  4.5]
  [ 4.4  5.3]
  [ 4.   6.3]]

 [[ 4.4  5.3]
  [ 5.1  5. ]
  [ 4.   6.3]]]

array2 =
[[ 4.2  4.5]
 [ 4.4  5.3]
 [ 4.5  4.8]
 [ 4.  6.3]]

如您所见,array1[1]的所有三个元素也都在array2中。所以我想从array1中删除array1[1]。
我尝试了For和If循环,但它不起作用。

for i in range(0,len(array1),1):
   if(array1[i][0] in array2 and array1[i][1] in array2 and array1[i][2] in array2):

       array1 = np.delete(array1, [i], axis=0)

   else:
      continue
print(array1)
2izufjch

2izufjch1#

一种可能的方法是使用np.isin函数,该函数返回一个布尔数组,指示一个数组中的每个元素是否包含在另一个数组中。例如,np.isin(array1, array2)将返回一个形状为(n,3,2)的布尔数组,其中array1的元素与array2的元素匹配。
然后,可以沿着最后一个轴使用np.all函数来检查array1的子数组的所有元素是否都在array2中。例如,np.all(np.isin(array1, array2), axis=-1)将返回具有True值的形状(n,3)的布尔数组,其中形状(2,)的子数组的所有元素都在array2中。
最后,您可以沿着第二个轴使用np.any函数来检查array1的任何子数组是否完全位于array2中。例如,np.any(np.all(np.isin(array1, array2), axis=-1), axis=1)将返回具有True值的形状(n,)的布尔数组,其中形状(3,2)的任何子数组都在array2中。
要从array1中删除array2中的元素,可以使用np.logic_not函数来反转布尔数组,并将其用作索引array1的掩码。例如,array1[np.logical_not(np.any(np.all(np.isin(array1, array2), axis=-1), axis=1))]将返回一个新数组,其中array1的元素不在array2中。

说明

此解决方案背后的逻辑是在不同的粒度级别比较array1和array2的元素,并使用布尔运算合并结果。

np.isin函数将array1的每个元素与整个array2进行比较,如果匹配则返回True。这是最基本的比较级别,它不考虑元素的顺序或结构。

沿最后一个轴的np.all函数将array1的形状(2,)的每个子数组与整个array2进行比较,如果子数组的所有元素都在array2中,则返回True。这是一种更精细的比较级别,它考虑了子数组中元素的顺序,但不考虑子数组的结构。
沿第二个轴的np.any函数将array1的形状(3,2)的每个子数组与整个array2进行比较,如果有任何子数组完全位于array2中,则返回True。这是最具体的比较级别,它考虑了子数组的顺序和结构。

np.logic_not函数用于反转布尔数组,因此True值变为False,反之亦然。这对于选择array1中不在array2中的元素非常有用,因为我们希望删除array2中的元素。

布尔数组可用作掩码来索引array1,并返回包含所选元素的新数组。这是解决方案的最后一步,它删除array1中array2中的元素。

示例

以下是实现解决方案并打印结果的一个python代码块:

import numpy as np

array1 = np.array([[[ 5.1,  5. ],
                    [ 6.2,  4.4],
                    [ 4. ,  6.3]],

                   [[ 4.22,  4.5],
                    [ 4.44,  5.3],
                    [ 4. ,  6.43]],

                   [[ 4.4,  5.3],
                    [ 5.1,  5. ],
                    [ 4. ,  6.3]]])

array2 = np.array([[ 4.22,  4.5],
                   [ 4.44,  5.3],
                   [ 4.5,  4.8],
                   [ 4. ,  6.43]])

mask = np.logical_not(np.any(np.all(np.isin(array1, array2), axis=-1), axis=1))
array1_after_deletion = array1[mask]
print(array1_after_deletion)

输出为:

[[[5.1 5. ]
  [6.2 4.4]
  [4.  6.3]]

 [[4.4 5.3]
  [5.1 5. ]
  [4.  6.3]]]

相关问题