Numpy: Resta 2 matrices numpy por fila

Tengo 2 matrices numpy a y b como a continuación:

a = np.random.randint(0,10,(3,2)) Out[124]: array([[0, 2], [6, 8], [0, 4]]) b = np.random.randint(0,10,(2,2)) Out[125]: array([[5, 9], [2, 4]]) 

Quiero restar cada fila en b de cada fila en a y la salida deseada es de forma (3,2,2):

 array([[[-5, -7], [-2, -2]], [[ 1, -1], [ 4, 4]], [[-5, -5], [-2, 0]]]) 

Puedo hacer esto usando:

 print(np.c_[(a - b[0]),(a - b[1])].reshape(3,2,2)) 

Pero necesito una solución completamente vectorizada o una función incorporada en números para hacer esto.

Simplemente use np.newaxis (que es solo un alias para Ninguno) para agregar una dimensión singleton a, y deje que la difusión haga el rest:

 In [45]: a[:, np.newaxis] - b Out[45]: array([[[-5, -7], [-2, -2]], [[ 1, -1], [ 4, 4]], [[-5, -5], [-2, 0]]]) 

No estoy seguro de lo que significa una solución completamente factorizada, pero puede que esto ayude:

 np.append(a, a, axis=1).reshape(3, 2, 2) - b 

Puedes ahorrar un poco de tiempo usando np.subtract (), y un poco más usando 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 

referencia:

Confundido sobre el documento numpy.c_ y el código de muestra.

np.c_ es otra forma de hacer concatenar matrices

Leyendo del documento sobre radiodifusión , dice:

Cuando se opera en dos matrices, NumPy compara sus formas de manera elemental. Comienza con las dimensiones finales, y se abre camino hacia adelante. Dos dimensiones son compatibles cuando

 they are equal, or one of them is 1 

De vuelta a su caso, quiere que el resultado esté en forma (3, 2, 2) , siguiendo estas reglas, tiene que jugar con sus dimensiones. Aquí está el código para hacerlo:

 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)