83

This had me scratching my head for a while. I was unintentionally slicing an array with None and getting something other than an error (I expected an error). Instead, it returns an array with an extra dimension.

>>> import numpy
>>> a = numpy.arange(4).reshape(2,2)
>>> a
array([[0, 1],
       [2, 3]])
>>> a[None]
array([[[0, 1],
        [2, 3]]])

Is this behavior intentional or a side-effect? If intentional, is there some rationale for it?

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Paul
  • 42,322
  • 15
  • 106
  • 123
  • 1
    Somewhat related, I've used slice(None) when I needed to pass something to slice but didn't want an extra dimension added. – Tahlor Aug 07 '18 at 20:03
  • 2
    `a[None]` is equivalent to `a[None, :, :]` or `a[None, ...]`. As with other indexing expressions, trailing slices are added as needed. Thus the `None` by itself, adds a new axis at the start. `a[...,None]` adds the new axis at the end. – hpaulj Dec 11 '18 at 00:45

1 Answers1

82

Using None is equivalent to using numpy.newaxis, so yes, it's intentional. In fact, they're the same thing, but, of course, newaxis spells it out better.

The docs:

The newaxis object can be used in all slicing operations to create an axis of length one. newaxis is an alias for ‘None’, and ‘None’ can be used in place of this with the same result.

A related SO question.

user2357112
  • 260,549
  • 28
  • 431
  • 505
tom10
  • 67,082
  • 10
  • 127
  • 137
  • 2
    It's intentional but is it logical? I would expect `array[None] == array` because I read it as "there is no mask applied". It would also feel more explicit to use something like `array.add_axis()` or `array = np.add_axis(array)` than `array = array[None]`. – Guimoute Jan 27 '21 at 15:12