Videos
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.
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
You need to wrap the indices in a list, not a tuple: x[[1,2]]. This triggers advanced indexing and NumPy returns a new array with the values at the indices you've written.
Whenever possible, NumPy implicitly assumes that each element of a tuple indexes a different dimension of the array. Your array has 1 dimension, not 2, hence x[(1,2)] raises an error.
The reason x[(1,2), :] succeeds with a 2D array is that you've explicitly told NumPy that the array has (at least) two dimensions and said what you want from the first two axes. The index is parsed as the 2-tuple ((1,2), :) so (1,2) is instead used for advanced indexing along the first axis. Had you simply used x[(1,2)] or x[1,2], you would get a single element at row 1, column 2.
Parsing the index is very complicated for NumPy because (unlike Python) there are several different indexing methods that can be used. To complicate things further, different methods may be used on different axes! You can study the exact implementation in NumPy's mapping.c file.
You need to put the indices in a list not tuple,numpy use tuples for indexing multi-dimensional arrays :
>>> x[[1,2]]
array([1, 2])
>>> x[(1,2)]
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
IndexError: too many indices
Another example :
>>> x = np.array([6,4,0,8,77,11,2,12,67,90])
>>> x[[6,0]]
array([2, 6])