You could also use np.choose:
gen = np.random.RandomState(0)
labels = gen.randint(3, size=(5, 6)) # random labels between 0 and 2
print(repr(labels))
# array([[0, 1, 0, 1, 1, 2],
# [0, 2, 0, 0, 0, 2],
# [1, 2, 2, 0, 1, 1],
# [1, 1, 0, 1, 0, 0],
# [1, 2, 0, 2, 0, 1]])
colors = np.array([[255, 0, 0], # red
[0, 255, 0], # green
[0, 0, 255]]) # blue
rgb = labels[..., None].choose(colors)
# labels[0, 1] == 1, so rgb[0, 1] should be [0, 255, 0] (i.e. green)
print(repr(rgb[0, 1]))
# array([ 0, 255, 0])
Another (much faster!) option would be np.take, e.g.:
rgb = colors.take(labels, axis=0)
This can be done more succinctly (but not quite as quickly) by using labels as an index array:
rgb = colors[labels]
Some benchmarking:
# my original answer
In [1]: %%timeit colors = np.random.randint(256, size=(11, 3)); labels = np.random.randint(11, size=(512, 512))
labels[..., None].choose(colors)
....:
10 loops, best of 3: 52 ms per loop
# Divakar's answer
In [2]: %%timeit colors = np.random.randint(256, size=(11, 3)); labels = np.random.randint(11, size=(512, 512))
colors[labels.ravel()].reshape(labels.shape+(3,))
....:
100 loops, best of 3: 4.44 ms per loop
# using take
In [3]: %%timeit colors = np.random.randint(256, size=(11, 3)); labels = np.random.randint(11, size=(512, 512))
colors.take(labels, axis=0)
....:
The slowest run took 4.96 times longer than the fastest. This could mean that an
intermediate result is being cached
1000 loops, best of 3: 1.25 ms per loop
# using integer array indexing
In [4]: %%timeit colors = np.random.randint(256, size=(11, 3)); labels = np.random.randint(11, size=(512, 512))
....: colors[labels]
....:
100 loops, best of 3: 4.19 ms per loop