我知道Python列表有一个方法可以返回某个对象的第一个索引:

>>> xs = [1, 2, 3]
>>> xs.index(2)
1

NumPy数组也有类似的东西吗?


当前回答

对于1D数组,我推荐np。平坦非零(array == value)[0],它等价于np。非零(array == value)[0][0]和np。其中(array == value)[0][0],但避免了对一个单元素元组开箱的丑陋。

其他回答

numpy中内置了一种相当习惯的向量化方法。它使用np.argmax()函数的一个奇怪之处来完成这一点——如果有许多值匹配,它将返回第一个匹配的索引。诀窍在于,对于布尔值,将永远只有两个值:True(1)和False(0)。因此,返回的索引将是第一个True的索引。

对于所提供的简单示例,您可以看到它在以下情况下工作

>>> np.argmax(np.array([1,2,3]) == 2)
1

一个很好的例子是计算桶,例如用于分类。假设你有一个切割点数组,你想要对应数组中每个元素的“桶”。该算法是计算x < cuts处的第一个切割索引(在使用np. infinity填充切割之后)。我可以使用broadcast来广播比较,然后沿着cuts-broadcast轴应用argmax。

>>> cuts = np.array([10, 50, 100])
>>> cuts_pad = np.array([*cuts, np.Infinity])
>>> x   = np.array([7, 11, 80, 443])
>>> bins = np.argmax( x[:, np.newaxis] < cuts_pad[np.newaxis, :], axis = 1)
>>> print(bins)
[0, 1, 2, 3]

正如预期的那样,x中的每个值都属于一个连续的箱子,具有定义良好且易于指定的边界情况行为。

您还可以将NumPy数组转换为list in - air并获取其索引。例如,

l = [1,2,3,4,5] # Python list
a = numpy.array(l) # NumPy array
i = a.tolist().index(2) # i will return index of 2
print i

它会输出1。

NumPy中有很多操作可以放在一起来完成这个任务。这将返回等于item的元素的下标:

numpy.nonzero(array - item)

然后你可以取列表的第一个元素来得到一个元素。

要在任何标准上建立索引,你可以这样做:

In [1]: from numpy import *
In [2]: x = arange(125).reshape((5,5,5))
In [3]: y = indices(x.shape)
In [4]: locs = y[:,x >= 120] # put whatever you want in place of x >= 120
In [5]: pts = hsplit(locs, len(locs[0]))
In [6]: for pt in pts:
   .....:         print(', '.join(str(p[0]) for p in pt))
4, 4, 0
4, 4, 1
4, 4, 2
4, 4, 3
4, 4, 4

这里有一个快速函数,它可以做list.index()所做的事情,只是如果没有找到它,它不会引发异常。注意——这在大型数组上可能非常慢。如果你想把它作为一个方法,你也可以把它拼凑到数组上。

def ndindex(ndarray, item):
    if len(ndarray.shape) == 1:
        try:
            return [ndarray.tolist().index(item)]
        except:
            pass
    else:
        for i, subarray in enumerate(ndarray):
            try:
                return [i] + ndindex(subarray, item)
            except:
                pass

In [1]: ndindex(x, 103)
Out[1]: [4, 0, 3]

如果你只需要第一次出现一个值的索引,你可以使用nonzero(或where,在这种情况下相当于相同的东西):

>>> t = array([1, 1, 1, 2, 2, 3, 8, 3, 8, 8])
>>> nonzero(t == 8)
(array([6, 8, 9]),)
>>> nonzero(t == 8)[0][0]
6

如果需要多个值中的每个值的第一个索引,显然可以重复执行上述操作,但有一个技巧可能更快。下面的代码查找每个子序列的第一个元素的下标:

>>> nonzero(r_[1, diff(t)[:-1]])
(array([0, 3, 5, 6, 7, 8]),)

注意,它找到了3s的子序列和8s的子序列的开头:

[1, 1, 1, 2, 2, 3, 8, 3, 8, 8]

这和求每个值的第一次出现有点不同。在你的程序中,你可以使用t的排序版本来得到你想要的:

>>> st = sorted(t)
>>> nonzero(r_[1, diff(st)[:-1]])
(array([0, 3, 5, 7]),)