我想创建一个numpy数组的掩码,标记包含另一个数组中的值的任何行

xfyts7mz  于 2023-10-19  发布在  其他
关注(0)|答案(2)|浏览(96)

我有一个numpy数组:

247 656 6363
13822   13818   30054
10174   25484   6553
6107    2927    6578
2904    6462    3941
16562   8692    16563
25182   6681    25181
6679    6429    3841

我想标记这个数组中的所有行,其中3列中的任何一列包含第二个数组的数字:

13822
13818
2927
8692
3841

这可能吗?
我希望结果提供一个列表或数组中的所有行的数组1包含这些值之一。
我已经四处寻找,并尝试使用numpy.mask,但无济于事。理想情况下,我希望返回包含第二个数组值的行的所有行号,以便稍后可以删除这些行。

ymzxtsji

ymzxtsji1#

我首先偷了@hpaulj的例子,所以这是值得称赞的。然后使用isin

import numpy as np

first = np.arange(15).reshape(5,3)
second = np.array([4,3,1,13])
res = np.isin(first, second)

print(res.any(axis=1))

我决定把这个计时出来,结果差别是天文数字:

import numpy as np
import timeit

first = np.arange(30000).reshape(-1,3)
second = np.random.randint(0, 30000, size=1000)

def add_dimension(first, second):
    res = (first[:,:,None]==second).any(axis=(1,2))
    return res
    
def with_isin(first, second):
    res = np.isin(first, second).any(axis=1)
    return res
    
print("With dimension:",timeit.timeit(lambda: add_dimension(first, second), number=1000))
print("With isin", timeit.timeit(lambda: with_isin(first, second), number=1000))

a = add_dimension(first, second)
b = with_isin(first, second)
print(np.array_equal(a, b))

这给了我:

With dimension: 15.245749666937627
With isin 0.18458845792338252
True
0md85ypi

0md85ypi2#

第一,使用3D比较阵列。
一对样品阵列:

In [184]: first = np.arange(15).reshape(5,3); second = np.array([4,3,1,13])

In [185]: first, second
Out[185]: 
(array([[ 0,  1,  2],
        [ 3,  4,  5],
        [ 6,  7,  8],
        [ 9, 10, 11],
        [12, 13, 14]]),
 array([ 4,  3,  1, 13]))

使用numpy广播比较2,结果是3d:

In [186]: first[:,:,None]==second
Out[186]: 
array([[[False, False, False, False],
        [False, False,  True, False],
        [False, False, False, False]],

       [[False,  True, False, False],
        [ True, False, False, False],
        [False, False, False, False]],

       [[False, False, False, False],
        [False, False, False, False],
        [False, False, False, False]],

       [[False, False, False, False],
        [False, False, False, False],
        [False, False, False, False]],

       [[False, False, False, False],
        [False, False, False,  True],
        [False, False, False, False]]])

现在检查所需的True组合。对于first的所有行,至少有一个True:

In [187]: (first[:,:,None]==second).any(axis=1)
Out[187]: 
array([[False, False,  True, False],
       [ True,  True, False, False],
       [False, False, False, False],
       [False, False, False, False],
       [False, False, False,  True]])

测试最后一行firstsecond(轴2):

In [188]: (first[:,:,None]==second).any(axis=(1,2))
Out[188]: array([ True,  True, False, False,  True])

和行索引:

In [189]: np.nonzero(_)
Out[189]: (array([0, 1, 4], dtype=int64),)

编辑

对于我的小例子,使用isin

In [191]: np.isin(first,second)
Out[191]: 
array([[False,  True, False],
       [ True,  True, False],
       [False, False, False],
       [False, False, False],
       [False,  True, False]])

In [192]: np.isin(first,second).any(axis=1)
Out[192]: array([ True,  True, False, False,  True])

In [193]: timeit np.isin(first,second).any(axis=1)
170 µs ± 338 ns per loop (mean ± std. dev. of 7 runs, 10,000 loops each)

In [194]: timeit (first[:,:,None]==second).any(axis=(1,2))
17.1 µs ± 101 ns per loop (mean ± std. dev. of 7 runs, 10,000 loops each)

以及按列测试迭代:

In [199]: timeit np.any([(first[:,i,None]==second).any(axis=1) for i in range(3)], axis=0)
84.1 µs ± 331 ns per loop (mean ± std. dev. of 7 runs, 10,000 loops each)

但与大多数计时一样,它们可以通过大型示例进行不同的缩放。

相关问题