Numpy:数组的重复掩码(如果我们之前见过该值,则返回 True,否则返回 False)

问题描述 投票:0回答:5

我正在寻找一个向量化函数,如果之前已经见过数组中的值,则返回值为 True 的掩码,否则返回 False。

我正在寻找尽可能最快的解决方案,因为速度非常重要。

例如,这就是我想看到的:

array = [1, 2, 1, 2, 3]
mask = [False, False, True, True, False]

所以

is_duplicate = array[mask]
应该返回
[1, 2]

有没有一种快速、矢量化的方法来做到这一点?谢谢!

python list numpy
5个回答
3
投票

方法#1:排序

def mask_firstocc(a):
    sidx = a.argsort(kind='stable')
    b = a[sidx]
    out = np.r_[False,b[:-1] == b[1:]][sidx.argsort()]
    return out

我们可以使用

array-assignment
来提高性能。进一步-

def mask_firstocc_v2(a):
    sidx = a.argsort(kind='stable')
    b = a[sidx]
    mask = np.r_[False,b[:-1] == b[1:]]
    out = np.empty(len(a), dtype=bool)
    out[sidx] = mask
    return out

样品运行 -

In [166]: a
Out[166]: array([2, 1, 1, 0, 0, 4, 0, 3])

In [167]: mask_firstocc(a)
Out[167]: array([False, False,  True, False,  True, False,  True, False])

方法#2: 使用

np.unique(..., return_index)

我们可以利用

np.unique
及其
return_index
,它似乎返回每个唯一元素的第一次出现,因此一个简单的数组赋值然后索引就可以了 -

def mask_firstocc_with_unique(a):
    mask = np.ones(len(a), dtype=bool)
    mask[np.unique(a, return_index=True)[1]] = False
    return mask

3
投票

使用

np.unique

a = np.array([1, 2, 1, 2, 3])
_, ix = np.unique(a, return_index=True)
b = np.full(a.shape, True)
b[ix] = False

In [45]: b
Out[45]: array([False, False,  True,  True, False])

0
投票

您可以使用

enumerate
方法来实现这一点 - 该方法允许您使用
index + value
进行循环:

array = [1, 2, 1, 2, 3]

mask = []

for i,v in enumerate(array):
  if array.index(v) == i:
    mask.append(False)
  else:
    mask.append(True)


print(mask)  

输出:

[False, False, True, True, False]

0
投票

虽然 np.unique 可能比排序方法慢,但这里有一个单行代码,为一维数组(或列表)提供灵活性和可读性:

mask = ~np.isin(np.arange(len(array)), np.unique(array, return_index=True)[1])
mask

array([False, False,  True,  True, False])

-1
投票

几乎根据定义,这不能矢量化。 任何

index
的掩码值取决于 0 到
array
之间每个值的
index
值。 可能有一些算法可以将
array
扩展为 NxN 矩阵并进行奇特的测试,但您仍然会拥有 O(n^2) 算法。 简单的集合算法是 O(n log n)。

© www.soinside.com 2019 - 2024. All rights reserved.