103

In numpy one can use the 'newaxis' object in the slicing syntax to create an axis of length one, e.g.:

import numpy as np
print np.zeros((3,5))[:,np.newaxis,:].shape
# shape will be (3,1,5)

The documentation states that one can also use None instead of newaxis, the effect is exactly the same.

Is there any reason to choose one over the other? Is there any general preference or style guide? My impression is that newaxis is more popular, probably because it is more explicit. So is there any reason why None is allowed?

nikow
  • 21,190
  • 7
  • 49
  • 70

1 Answers1

118

None is allowed because numpy.newaxis is merely an alias for None.

In [1]: import numpy

In [2]: numpy.newaxis is None
Out[2]: True

The authors probably chose it because they needed a convenient constant, and None was available.

As for why you should prefer newaxis over None: mainly it's because it's more explicit, and partly because someday the numpy authors might change it to something other than None. (They're not planning to, and probably won't, but there's no good reason to prefer None.)

AFoglia
  • 7,968
  • 3
  • 35
  • 51
  • 8
    They actually say you can use None, though, so they can't change it now: "The newaxis object can be used in the basic slicing syntax discussed above. None can also be used instead of newaxis." – endolith Jun 05 '12 at 20:37
  • 5
    Also if you work with people unfamiliar with the details of numpy indexing they seem to go crazy when they see arrays dereferenced by "None" – Peter Nov 16 '15 at 13:03
  • 1
    One place when `None` is better is optimization of execution speed, it can give a very tiny time benefit. But usually you should prefer `np.newaxis`. – godaygo May 05 '17 at 11:20
  • @Ethunxxx try to `import dis; dis.dis('None')` vs `import dis; dis.dis('np.newaxis')` and see the difference in bytecode. You wouldn't see huge boost, but nevertheless. For future question, `LOAD_CONST` is faster then `LOAD_NAME`. – godaygo Dec 07 '17 at 09:03
  • 5
    Why they just didn't use `newaxis = object()` (or the C-level equivalent) is beyond me... using `None` is quite error-prone. I had a function with a bug (a bare `return` that was supposed to return a boolean array) and I started getting errors due to shape mismatch. Took me a while to realize that indexing with `None` doesn't simply raise an `IndexError`. If they had used a "fresh" sentinel value I'd avoided 30 mins of trying to make sense of the error... – Giacomo Alzetta Aug 03 '18 at 15:21
  • 1
    Also, don't be tempted to substitute `a[slice(None)]` for `a[None]`. `slice(None)` means *everything*. Rather obvious, isn't it? – adr Nov 02 '21 at 11:17