I have 2 numpy arrays a and b as below:
a = np.random.randint(0,10,(3,2))
Out[124]:
array([[0, 2],
[6, 8],
[0, 4]])
b = np.random.randint(0,10
You can shave a little time off using np.subtract(), and a good bit more using np.concatenate()
import numpy as np
import time
start = time.time()
for i in range(100000):
a = np.random.randint(0,10,(3,2))
b = np.random.randint(0,10,(2,2))
c = np.c_[(a - b[0]),(a - b[1])].reshape(3,2,2)
print time.time() - start
start = time.time()
for i in range(100000):
a = np.random.randint(0,10,(3,2))
b = np.random.randint(0,10,(2,2))
#c = np.c_[(a - b[0]),(a - b[1])].reshape(3,2,2)
c = np.c_[np.subtract(a,b[0]),np.subtract(a,b[1])].reshape(3,2,2)
print time.time() - start
start = time.time()
for i in range(100000):
a = np.random.randint(0,10,(3,2))
b = np.random.randint(0,10,(2,2))
#c = np.c_[(a - b[0]),(a - b[1])].reshape(3,2,2)
c = np.concatenate([np.subtract(a,b[0]),np.subtract(a,b[1])],axis=1).reshape(3,2,2)
print time.time() - start
>>>
3.14023900032
3.00368094444
1.16146492958
reference:
confused about numpy.c_ document and sample code
np.c_ is another way of doing array concatenate
Just use np.newaxis
(which is just an alias for None) to add a singleton dimension to a, and let broadcasting do the rest:
In [45]: a[:, np.newaxis] - b
Out[45]:
array([[[-5, -7],
[-2, -2]],
[[ 1, -1],
[ 4, 4]],
[[-5, -5],
[-2, 0]]])
I'm not sure what means a fully factorized solution, but may be this will help:
np.append(a, a, axis=1).reshape(3, 2, 2) - b
Reading from the doc on broadcasting, it says:
When operating on two arrays, NumPy compares their shapes element-wise. It starts with the trailing dimensions, and works its way forward. Two dimensions are compatible when
they are equal, or one of them is 1
Back to your case, you want result to be of shape (3, 2, 2)
, following these rules, you have to play around with your dimensions.
Here's now the code to do it:
In [1]: a_ = np.expand_dims(a, axis=0)
In [2]: b_ = np.expand_dims(b, axis=1)
In [3]: c = a_ - b_
In [4]: c
Out[4]:
array([[[-5, -7],
[ 1, -1],
[-5, -5]],
[[-2, -2],
[ 4, 4],
[-2, 0]]])
In [5]: result = c.swapaxes(1, 0)
In [6]: result
Out[6]:
array([[[-5, -7],
[-2, -2]],
[[ 1, -1],
[ 4, 4]],
[[-5, -5],
[-2, 0]]])
In [7]: result.shape
Out[7]: (3, 2, 2)