web-dev-qa-db-fra.com

numpy soustrayez chaque ligne de la matrice par vecteur

Donc j'ai un n x d matrice et un n x 1 vecteur. J'essaie d'écrire un code pour soustraire chaque ligne de la matrice par le vecteur.

J'ai actuellement une boucle for qui parcourt et soustrait le i - ième ligne de la matrice par le vecteur. Y a-t-il un moyen de soustraire simplement une matrice entière par le vecteur?

Merci!

Code actuel:

for i in xrange( len( X1 ) ):
    X[i,:] = X1[i,:] - X2

C'est ici que X1 est la matrice i - ième ligne et X2 est un vecteur. Puis-je faire en sorte que je n'ai pas besoin d'une boucle for?

42
thehandyman

Cela fonctionne dans numpy mais uniquement si les axes de fin ont la même dimension . Voici un exemple de soustraction réussie d'un vecteur à une matrice:

In [27]: print m; m.shape
[[ 0  1  2]
 [ 3  4  5]
 [ 6  7  8]
 [ 9 10 11]]
Out[27]: (4, 3)

In [28]: print v; v.shape
[0 1 2]
Out[28]: (3,)

In [29]: m  - v
Out[29]: 
array([[0, 0, 0],
       [3, 3, 3],
       [6, 6, 6],
       [9, 9, 9]])

Cela a fonctionné car l'axe de fuite des deux avait la même dimension (3).

Dans votre cas, les axes principaux avaient la même dimension. Voici un exemple, en utilisant le même v que ci-dessus, de la façon dont cela peut être corrigé:

In [35]: print m; m.shape
[[ 0  1  2  3]
 [ 4  5  6  7]
 [ 8  9 10 11]]
Out[35]: (3, 4)

In [36]: (m.transpose() - v).transpose()
Out[36]: 
array([[0, 1, 2, 3],
       [3, 4, 5, 6],
       [6, 7, 8, 9]])

Les règles pour les axes de diffusion sont expliquées en profondeur ici .

56
John1024

En plus de la réponse @ John1024, la "transposition" d'un vecteur unidimensionnel dans numpy peut être effectuée comme suit:

In [1]: v = np.arange(3)

In [2]: v
Out[2]: array([0, 1, 2])

In [3]: v = v[:, np.newaxis]

In [4]: v
Out[4]:
array([[0],
       [1],
       [2]])

À partir de là, soustraire v de chaque colonne de m est trivial en utilisant la diffusion:

In [5]: print(m)
[[ 0  1  2  3]
 [ 4  5  6  7]
 [ 8  9 10 11]]

In [6]: m - v
Out[6]:
array([[0, 1, 2, 3],
       [3, 4, 5, 6],
       [6, 7, 8, 9]])
10
Nagasaki45