问题
I did read on numpy indexing but I didn't find what I was looking for.
I have a 288*384 image, where each pixel can have a labelling in [0,15].
It is stored in a 3d (288,384,16)-shaped numpy array im
.
With im[:,:,1]
, I can for example get the image where all pixels have the label 1.
I have another 2d array labelling
, (288*384)-shaped, containing a label for each pixel.
How do I get the image where each pixel has the corresponding pixel using some clever slicing?
Using loops, that would be:
result = np.zeros((288,384))
for x,y in zip(range(288), range(384)):
result[x,y] = im[x,y,labelling[x,y]]
But this is of course inefficient.
回答1:
New Result
The short result is
np.choose(labelling,im.transpose(2,0,1))
Old Result
Try this
im[np.arange(288)[:,None],np.arange(384)[None,:],labelling]
It works for the following situation:
import numpy
import numpy.random
import itertools
a = numpy.random.randint(5,size=(2,3,4))
array([[[4, 4, 0, 0],
[0, 4, 1, 1],
[3, 4, 4, 2]],
[[4, 0, 0, 2],
[1, 4, 2, 2],
[4, 2, 4, 4]]])
b = numpy.random.randint(4,size=(2,3))
array([[1, 1, 0],
[1, 2, 2]])
res = a[np.arange(2)[:,None],np.arange(3)[None,:],b]
array([[4, 4, 3],
[0, 2, 4]])
# note that zip is not doing what you expect it to do
result = np.zeros((2,3))
for x,y in itertools.product(range(2),range(3)):
result[x,y] = a[x,y,b[x,y]]
array([[4., 4., 3.],
[0., 2., 4.]])
Note that zip
is not doing what you expect
zip(range(2),range(3))
[(0, 0), (1, 1)]
Probably you meant something like itertools.product
list(itertools.product(range(2),range(3)))
[(0, 0), (0, 1), (0, 2), (1, 0), (1, 1), (1, 2)]
The horribly looking [:,None]
etc. can be avoided by using numpy.ix_
xx,yy = np.ix_( np.arange(2), np.arange(3) )
res = a[xx,yy,b]
来源:https://stackoverflow.com/questions/29098417/numpy-get-2d-array-where-last-dimension-is-indexed-according-to-a-2d-array