2

It is hard to find a clear title but an example will put it clearly. For example, my inputs are:

c = np.full((4, 3, 2), 5)
c[:,:,1] *= 2

ix = np.random.randint(0, 2, (4, 3))

if ix is:

array([[1, 0, 1],
       [0, 0, 1],
       [0, 0, 1],
       [1, 1, 0]])

if want as a result:

array([[10,  5, 10],
       [ 5,  5, 10],
       [ 5,  5, 10],
       [10, 10,  5]])

My c array can be of arbitrary dimensions, as well a the dimension I want to sample in.

It sounds like interpolation, but I'm reluctant to construct a be array of indices each time I want to apply this. Is there a way of doing this using some kind of indexing on numpy arrays ? Or do I have to use some interpolation methods... Speed and memory are a concern here because I have to do this many times, and the arrays can be really large.

Thanks for any insight !

beesleep
  • 1,322
  • 8
  • 18

1 Answers1

4

Create the x, y indices with numpy.ogrid, and then use advanced indexing:

idx, idy = np.ogrid[:c.shape[0], :c.shape[1]]
c[idx, idy, ix]

#array([[10,  5, 10],
#       [ 5,  5, 10],
#       [ 5,  5, 10],
#       [10, 10,  5]])
Psidom
  • 209,562
  • 33
  • 339
  • 356
  • Thanks for you answer! I was wondering if I could avoid to create the grid... But i no other solution, I'll accept yours ! – beesleep Aug 24 '18 at 14:20
  • `ogrid` is an 'open' grid, with (4,1) and (1,3) arrays. So there's nothing particularly expensive about them. You just need a pair that broadcasts with your `ix`. `np.ix_(range(4), range(3))` produces the same pair. – hpaulj Aug 24 '18 at 15:58