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 isx.ndim
. There may only be a single ellipsis present.
Related Topics
Sorting a List of Dot-Separated Numbers, Like Software Versions
Postponing Functions in Python
How to Convert a Numpy Array to (And Display) an Image
Get Lat/Long Given Current Point, Distance and Bearing
Redirecting Stdout and Stderr to a Pyqt4 Qtextedit from a Secondary Thread
Ssl.Sslerror: Tlsv1 Alert Protocol Version
Cs50: Like Operator, Variable Substitution with % Expansion
Convert to Binary and Keep Leading Zeros
Scraping Google Finance (Beautifulsoup)
Defining a Discrete Colormap for Imshow in Matplotlib
How to Do Exponentiation in Python
How to Implement Server Push in Flask Framework
Pip Installing in Global Site-Packages Instead of Virtualenv
Pandas: To_Numeric for Multiple Columns
Transparent Background in a Tkinter Window
Databaseerror: Current Transaction Is Aborted, Commands Ignored Until End of Transaction Block