Skip to content Skip to sidebar Skip to footer

Broadcast Advanced Indexing Numpy

I have an array of values for example x = array([[[-0.78867513, -0.21132487, 0. , 0.78867513, 0.21132487, 0. , 0. , 0. , 0. ],

Solution 1:

Try this one:

x[:,np.arange(idx.shape[0])[:,None],idx]

Using this technique every element in np.arange(idx.shape[0])[:,None] (which has shape (idx.shape[0], 1) and therefore is a column vector) will be broadcast with every row in idx. This will then be used for all entries along x's first axis.


Solution 2:

I tried this one liner for your problem and it seems to do the job without needing idx. You may need to change the parameter in .reshape() according to the size of your problem.

np.array(filter(lambda x: x!=0, x.ravel())).reshape(-1, 4, 4)

It flattens the array, removes the zeroes and then changes it back to the required shape.

Here's another version which is probably more efficient as it does not use the filter function and uses boolean indexing for numpy arrays instead

y = x.ravel()
z = y[y!=0].reshape(-1, 4, 4)

EDIT:

While playing around with numpy I discovered yet another way to do it.

x[x!=0].reshape(-1, 4, 4)

And here's the performance of all three method:

  • Method 1: 10000 loops, best of 3: 21.2 µs per loop
  • Method 2: 100000 loops, best of 3: 2.42 µs per loop
  • Method 3: 100000 loops, best of 3: 1.97 µs per loop

Solution 3:

OK, this is a bit odd, but here goes...

idxes = np.ones((x.shape[0], x.shape[1], 1), dtype=bool) * idx
print x[np.array(x, dtype=bool)].reshape(idxes.shape)

And of course you must remember to write np.array rather than array.

Cheers!

And you can unburden yourself from computing idx with the following:

y = x[np.array(x, dtype=bool)]
print y.reshape(x.shape[0], x.shape[1], y.size/x.shape[0]/x.shape[1])

With this or the lines above it's the casting of the floats as bools that provides a mask that eliminates the zeros.


Post a Comment for "Broadcast Advanced Indexing Numpy"