寻找在numpy中最快的办法找出两个等长数组的确切重叠

4 投票
3 回答
4613 浏览
提问于 2025-04-15 18:32

我在寻找在numpy中找到两个数组完全重叠的最快方法。假设有两个数组x和y。

x = array([1,0,3,0,5,0,7,4],dtype=int)
y = array([1,4,0,0,5,0,6,4],dtype=int)

我想得到的是一个长度相同的数组,这个数组只包含两个向量中相等的数字:

array([1,0,0,0,5,0,0,4])

我最开始尝试了

x&y
array([1,0,0,0,5,0,6,4])

然后我意识到,对于两个大于0的数字,这个情况总是成立。

3 个回答

0

试试使用 numpy.in1d... 来查看文档...

这个功能可以检查一个一维数组中的每个元素是否也在另一个数组中。

它会返回一个布尔数组,长度和 ar1 一样,里面的值是 True 表示 ar1 中的某个元素在 ar2 中找到了,False 则表示没有找到。

参数

ar1 : 类数组,形状为 (M,) 输入的数组。 ar2 : 类数组 用来测试 ar1 中每个值的数组。 assume_unique : 布尔值,可选 如果设置为 True,表示输入的数组都被认为是唯一的,这样可以加快计算速度。默认是 False。

返回值

mask : 布尔型的 ndarray,形状为 (M,) ar1[mask] 中的值在 ar2 中。

相关内容

numpy.lib.arraysetops : 这个模块里有很多其他函数,可以对数组进行集合操作。

注意事项

in1d 可以看作是 Python 关键字 in 的元素级函数版本,适用于一维序列。in1d(a, b) 大致等同于 np.array([item in b for item in a])

.. 版本更新于:: 1.4.0

示例

test = np.array([0, 1, 2, 5, 0])
states = [0, 2]
mask = np.in1d(test, states)
mask
    array([ True, False,  True, False,  True], dtype=bool)
test[mask]
    array([0, 2, 0])
2

使用 numpy.where 是一个很通用的解决方案。但是在这个特定的情况下,出于良好的编程习惯,你可以用 x==y 来作为一个筛选条件:

mask = x==y  
# mask is  array([ True, False, False,  True,  True,  True, False,  True], dtype=bool)

xf = mask * x
# xf is array([1, 0, 0, 0, 5, 0, 0, 4])

或者直接这样做:

xf = (x==y) * x

现在想象一下有一些数据 X(比如说一维数据可以代表声音,二维数据可以代表图像,三维数据可以代表电影等等...)

(X<1) * -1. + (X>1) * 1.

这个方法会返回数据,对于幅度小于1的值返回 -1,否则返回 1.

6
result = numpy.where(x == y, x, 0)

你可以查看一下numpy.where的文档,里面有详细的解释。简单来说,numpy.where(a, b, c)这个函数会根据条件a返回一个和a形状一样的数组,数组里的值会根据a的每个元素是“真”还是“假”来选择bc。而bc可以是单个数字。

顺便提一下,x & y并不一定对两个正数“总是为真”。它实际上是对xy的每个元素进行按位与操作:

x = numpy.array([2**p for p in xrange(10)])
# x is [  1   2   4   8  16  32  64 128 256 512]
y = x - 1
# y is [  0   1   3   7  15  31  63 127 255 511]
x & y
# result: [0 0 0 0 0 0 0 0 0 0]

这是因为x中每个元素的按位表示形式是1后面跟着n个零,而y中对应的元素是n1。一般来说,对于两个非零的数字aba & b可能等于零,也可能不等于零,但不一定等于ab中的任何一个。

撰写回答