序列中的numpy数组的索引

时间:2017-10-19 21:20:56

标签: python numpy

我想在序列中找到特定numpy数组的索引。例如,给定:

import numpy as np

WHITE = np.array([255, 255, 255])
BLUE = np.array([0, 0, 255])
GRAY = np.array([192, 192, 192])
BLACK = np.array([0, 0, 0])
GREEN = np.array([0, 255, 0])
YELLOW = np.array([255, 255, 0])
COLORS = (WHITE, BLUE, GRAY, BLACK, GREEN)

我希望能够要求像

这样的东西
print(COLORS.index(GRAY))

但这会导致错误:

ValueError: The truth value of an array with more than one element
is ambiguous. Use a.any() or a.all()

我确实有一个解决方法,但感觉过于杂技:

def index_of(x, sequence):
    eq = list((item == x).all() for item in sequence)
    return eq.index(True)

print(index_of(GRAY, COLORS))

有没有更优雅/ Pythonic的方法来做到这一点?

3 个答案:

答案 0 :(得分:2)

可能是品味问题,但在这种情况下,for循环可能更具可读性:

def index_of(search_for, arrays):
    for i, array in enumerate(arrays):
        if np.array_equal(search_for, array):
            return i
    raise ValueError('{} not in sequence'.format(search_for))

numpy函数np.array_equal允许比较不同大小的数组,以备不时之需((item == x).all()会针对不同的数组大小引发异常)

同时引发ValueError例外以模仿元组的index函数。

答案 1 :(得分:1)

考虑到您不是按值而是按实际对象编制索引,您应该可以使用is

def index_of(color, seq):
    return next(i for i, x in enumerate(seq) if x is color)

答案 2 :(得分:0)

如果COLORS是列表列表,则index有效:

In [39]: C = [c.tolist() for c in COLORS]
In [40]: C
Out[40]: [[255, 255, 255], [0, 0, 255], [192, 192, 192], [0, 0, 0], [0, 255, 0]]
In [41]: C.index(GRAY.tolist())
Out[41]: 2

对于数组元素,index执行如下操作:

In [44]: [c==GRAY for c in COLORS]
Out[44]: 
[array([False, False, False], dtype=bool),
 array([False, False, False], dtype=bool),
 array([ True,  True,  True], dtype=bool),
 array([False, False, False], dtype=bool),
 array([False, False, False], dtype=bool)]

数组的等式测试是逐个元素完成的,结果是一个布尔数组。但是在需要简单标量布尔值的上下文中使用布尔数组会导致(太常见)模糊度错误。 all可以将这些数组减少为单个值。

In [46]: [(c==GRAY).all() for c in COLORS]
Out[46]: [False, False, True, False, False]

In [47]: [(c==GRAY).all() for c in COLORS].index(True)
Out[47]: 2
In [48]: [(c==BLUE).all() for c in COLORS].index(True)
Out[48]: 1

如果将COLORS转换为2d数组,我们可以执行以下测试:

In [49]: CA = np.array(COLORS)
In [50]: CA
Out[50]: 
array([[255, 255, 255],
       [  0,   0, 255],
       [192, 192, 192],
       [  0,   0,   0],
       [  0, 255,   0]])
In [51]: CA==GRAY
Out[51]: 
array([[False, False, False],
       [False, False, False],
       [ True,  True,  True],
       [False, False, False],
       [False, False, False]], dtype=bool)
In [52]: (CA==GRAY).all(axis=1)
Out[52]: 
array([False, False,  True, False, False], dtype=bool)