我想在序列中找到特定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的方法来做到这一点?
答案 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)