Numpy Index Slice Without Losing Dimension Information

Numpy index slice without losing dimension information

It's probably easiest to do x[None, 10, :] or equivalently (but more readable) x[np.newaxis, 10, :]. None or np.newaxis increases the dimension of the array by 1, so that you're back to the original after the slicing eliminates a dimension.

As far as why it's not the default, personally, I find that constantly having arrays with singleton dimensions gets annoying very quickly. I'd guess the numpy devs felt the same way.

Also, numpy handle broadcasting arrays very well, so there's usually little reason to retain the dimension of the array the slice came from. If you did, then things like:

a = np.zeros((100,100,10))
b = np.zeros(100,10)
a[0,:,:] = b

either wouldn't work or would be much more difficult to implement.

(Or at least that's my guess at the numpy dev's reasoning behind dropping dimension info when slicing)

Pythonic way to index without losing dimensions

You can also do it with a list of indices with a single element:

>>> data[[2]].shape
(1, 16, 16)

As for which is more pythonic, that is more opinion-based than anything.


Note: This method will create a copy of the data instead of a view into the same data since arbitrary indices might not result in a contiguous view. This is explained in detail in the question Avoid copying when indexing a numpy arrays using lists

What is the best way to keep dimensionality when subarraying numpy arrays?

Just use slicing rather than indexing, and the shape will be preserved:

a[1:2]

Preserving the dimensions of a slice from a Numpy 3d array

a[:,:,[5]].shape
# (10,10,1)

a[:,:,5] is an example of basic slicing.

a[:,:,[5]] is an example of integer array indexing -- combined with basic slicing. When using integer array indexing the resultant shape is always "identical to the (broadcast) indexing array shapes". Since [5] (as an array) has shape (1,),
a[:,:,[5]] ends up having shape (10,10,1).

Numpy slice with preserving dimensions

https://docs.scipy.org/doc/numpy/user/basics.indexing.html#boolean-or-mask-index-arrays

Unlike in the case of integer index arrays, in the boolean case, the result is a 1-D array containing all the elements in the indexed array corresponding to all the true elements in the boolean array.

It expands on the case where arr1 has more dimensions than the mask. But the basic point is there's logically nothing else it can return.

Look at cond (maybe for a smaller case). How else do you map the True values on to a (11,300) array?

Have you looked at masked arrays? That keeps the original shape, replacing the 'masked' values with '--' (in the display).


In [284]: arr1 =np.random.randint(0,10,(4,5))
In [285]: arr1
Out[285]:
array([[4, 6, 5, 8, 8],
[4, 0, 4, 8, 1],
[3, 9, 0, 3, 2],
[8, 8, 7, 5, 7]])
In [286]: mask = arr1<4
In [287]: mask
Out[287]:
array([[False, False, False, False, False],
[False, True, False, False, True],
[ True, False, True, True, True],
[False, False, False, False, False]], dtype=bool)
In [288]: arr1[mask]
Out[288]: array([0, 1, 3, 0, 3, 2])
In [289]: arrM=np.ma.MaskedArray(arr1,~mask)
In [290]: arrM
Out[290]:
masked_array(data =
[[-- -- -- -- --]
[-- 0 -- -- 1]
[3 -- 0 3 2]
[-- -- -- -- --]],
mask =
[[ True True True True True]
[ True False True True False]
[False True False False False]
[ True True True True True]],
fill_value = 999999)

Numpy slice of arbitrary dimensions

There is ... or Ellipsis, which does exactly this:

slice = myarray[..., i]

Ellipsis is the python object, if you should want to use it outside the square bracket notation.

How to index/slice the last dimension of a PyTorch tensor/numpy array of unknown dimensions

PyTorch support NumPy-like indexing so you can use Ellipsis(...)

>>> z[..., -1:]

Example:

>>> x                     # (2,2) tensor
tensor([[0.5385, 0.9280],
[0.8937, 0.0423]])
>>> x[..., -1:]
tensor([[0.9280],
[0.0423]])
>>> y                     # (2,2,2) tensor
tensor([[[0.5610, 0.8542],
[0.2902, 0.2388]],

[[0.2440, 0.1063],
[0.7201, 0.1010]]])
>>> y[..., -1:]
tensor([[[0.8542],
[0.2388]],

[[0.1063],
[0.1010]]])
  • Ellipsis (...) expands to the number of : objects needed for the selection tuple to index all dimensions. In most cases, this means that length of the expanded selection tuple is x.ndim. There may only be a single ellipsis present.


Related Topics



Leave a reply



Submit