我会尝试回答问题的第二部分。
所以,我们正在比较:
A[np.all(np.any((A-B[:, None]), axis=2), axis=0)] (I)
而且。
A[~((A[:,None,:] == B).all(-1)).any(1)]
与第一种方法进行匹配对比,我们可以将第二种方法写成这样 -
A[(((~(A[:,None,:] == B)).any(2))).all(1)] (II)
主要区别在于性能方面,第一种方法使用减法获取非匹配值,并检查
.any()
中的非零值。因此,
any()
被设计用于处理非布尔类型数组。而在第二种方法中,我们使用
A[:,None,:] == B
生成布尔数组并将其传递给
any()
。
让我们进行一个小型的运行时测试以查看
.any()
在
int
dtype和
boolean array
上的表现 -
In [141]: A = np.random.randint(0,9,(1000,1000))
In [142]: %timeit A.any(0)
1000 loops, best of 3: 1.43 ms per loop
In [143]: A = np.random.randint(0,9,(1000,1000))>5
In [144]: %timeit A.any(0)
10000 loops, best of 3: 164 µs per loop
所以,通过在这部分上近乎
9倍
的加速,我们看到使用布尔数组的
any()
方法有巨大优势。我认为这是使第二种方法更快的最大原因。
setdiff1d
在幕后需要进行大量的完整排序操作,而上面的代码行只是分配了一个内存块,填充它,然后将其缩减为一个一维数组以索引A
。然而,当A
和B
变得更大时(可能需要分配和填充大量的内存块),使用诸如(A[:,None,:] == B)
的代码会变得非常低效,因此它实际上可能会变成更慢的选项。 - Alex Riley