np.where是否有更快的替代方法来确定指标?

时间:2020-04-21 19:28:20

标签: python numpy

我有一个像这样的数组:

arrayElements = [[1, 4, 6],[2, 4, 6],[3, 5, 6],...,[2, 5, 6]]

例如,我需要知道arrayElements等于1的索引。

现在,我正在做

rows, columns = np.where(arrayElements == 1)

这有效,但是我在一个循环中执行此操作,循环遍历所有可能的元素值,在我的情况下为1-500,000 +。根据阵列的大小,这需要30-40分钟才能运行。任何人都可以提出更好的解决方案吗? (其他信息是,我不在乎值所在的列,仅在行中,不确定是否有用)。

编辑:我需要分别知道每个元素的值。也就是说,我需要元素包含的每个值的行值。

3 个答案:

答案 0 :(得分:2)

通过使用np.isin(请参阅documentation),您可以测试多个元素值。 例如:

import numpy as np 

a = np.array([1,2,3,4])
check_for = np.array([1,2])

locs = np.isin(a, check_for)
# [True,  True, False, False]

np.where(locs)
#[0, 1]

注意:这假设您不需要分别了解每个元素值的索引。

如果需要分别跟踪每个元素值,请使用默认字典并遍历矩阵。

from collections import defaultdict

tracker = defaultdict(set)

for (row, column), value in np.ndenumerate(arrayElements):
    tracker[value].add(row)

答案 1 :(得分:2)

因此,您正在生成成千上万个这样的数组:

In [271]: [(i,np.where(arr==i)[0]) for i in range(1,7)]                                                
Out[271]: 
[(1, array([0])),
 (2, array([1, 3])),
 (3, array([2])),
 (4, array([0, 1])),
 (5, array([2, 3])),
 (6, array([0, 1, 2, 3]))]

我可以通过广播一点一次对所有值进行==测试:

In [281]: arr==np.arange(1,7)[:,None,None]                                                             
Out[281]: 
array([[[ True, False, False],
        [False, False, False],
        [False, False, False],
        [False, False, False]],

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

       [[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,  True, False],
        [False,  True, False]],

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

并且由于您只关心行,因此请应用any

In [282]: (arr==np.arange(1,7)[:,None,None]).any(axis=2)                                               
Out[282]: 
array([[ True, False, False, False],
       [False,  True, False,  True],
       [False, False,  True, False],
       [ True,  True, False, False],
       [False, False,  True,  True],
       [ True,  True,  True,  True]])

where的值与Out [271]中的值相同,但分组方式不同:

In [283]: np.where((arr==np.arange(1,7)[:,None,None]).any(axis=2))                                     
Out[283]: 
(array([0, 1, 1, 2, 3, 3, 4, 4, 5, 5, 5, 5]),
 array([0, 1, 3, 2, 0, 1, 2, 3, 0, 1, 2, 3]))

可以将其拆分为:

In [284]: from collections import defaultdict                                                          
In [285]: dd = defaultdict(list)                                                                       
In [287]: for i,j in zip(*Out[283]): dd[i].append(j)                                                   
In [288]: dd                                                                                           
Out[288]: 
defaultdict(list,
            {0: [0], 1: [1, 3], 2: [2], 3: [0, 1], 4: [2, 3], 5: [0, 1, 2, 3]})

尽管某些方法可能无法很好地解决您的全部问题,但第二种方法可能对某些阵列更快。

答案 2 :(得分:0)

您可以尝试使用numpy.ndenumerateCounterdefaultdictdict(其中键是数组中的值)遍历值和索引。

相关问题