If I had two numpy arrays that looked like this
a = np.array([1, 2])
b = np.array([3, 4])
and I wanted to add all pairwise combinations, I could easily do
c = a + b[:, None]
c
array([[4, 5],
[5, 6]])
to get the result of 1+3, 2+3 and 1+4, 2+4.
Why does this work? What is 'None' doing? I can print out
b[:, None]
[[3]
[4]]
But I'm not sure why that tells numpy to do pairwise combos. I'm also curious about if it's efficiently implemented under the hood compared to, say, itertools.combinations.
To answer the first part of your question, b[:, None] is a special type of slicing that has identical behavior to b[:, np.newaxis], in that it adds an axis of length 1 to your array.
>>> b.shape
(2,)
>>> b[:, None].shape
(2, 1)
This behavior is documented in the numpy docs [1], emphasis mine:
The
newaxisobject can be used in all slicing operations to create an axis of length one.newaxisis an alias forNone, andNonecan be used in place of this with the same result.
So now we have two arrays:
array([1, 2]) + array([[3],
[4]])
Summing these two arrays results in:
array([[4, 5],
[5, 6]])
The "magic" behind this is numpy broadcasting[2]. This article [3] is an excellent resource for beginning to understand the topic.
The main takeaways from the article are as follows:
numpy operations are usually done element-by-element which requires two arrays to have exactly the same shape. However, this constraint is relaxed if both arrays have the same trailing axis, or if one of the trailing axes is equal to one (which is the behavior being exhibited in your case).
In your case, broadcasting occurs, so the operation is equivalent to summing the following 2x2 arrays:
array([[1, 2], + array([[3, 3],
[1, 2]]) [4, 4]])
Which, since numpy operations are done element-by-element, will produce the desired output of:
array([[4, 5],
[5, 6]])
[1]https://docs.scipy.org/doc/numpy/reference/arrays.indexing.html#numpy.newaxis
[2]https://docs.scipy.org/doc/numpy-1.13.0/user/basics.broadcasting.html
[3]http://scipy.github.io/old-wiki/pages/EricsBroadcastingDoc
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With