Comment obtenir une multiplication matricielle par élément (produit Hadamard) dans numpy?


104

J'ai deux matrices

a = np.matrix([[1,2], [3,4]])
b = np.matrix([[5,6], [7,8]])

et je veux obtenir le produit élément par élément [[1*5,2*6], [3*7,4*8]], égalant

[[5,12], [21,32]]

j'ai essayé

print(np.dot(a,b)) 

et

print(a*b)

mais les deux donnent le résultat

[[19 22], [43 50]]

qui est le produit de la matrice, pas le produit élément par élément. Comment puis-je obtenir le produit élément par élément (alias produit Hadamard) à l'aide des fonctions intégrées?


4
Êtes-vous sûr aet bn'êtes pas le type de matrice de NumPy? Avec cette classe, *renvoie le produit interne, pas par élément. Mais pour la ndarrayclasse habituelle , *signifie produit élément par élément.
bnaecker

sont aet des btableaux numpy? De plus, dans votre question ci-dessus, vous utilisez xet ypour le calcul au lieu de aet b. Est-ce juste une faute de frappe?
jtitusj

a et b sont des éléments de type matrice
numpy

8
Utilisez toujours des tableaux numpy, et non des matrices numpy. Voyez ce que les documents numpy disent à ce sujet. Notez également qu'à partir de python 3.5+, vous pouvez utiliser @pour la multiplication de matrice avec des tableaux numpy, ce qui signifie qu'il ne devrait y avoir absolument aucune bonne raison d'utiliser des matrices sur des tableaux.
Praveen

3
Pour être pointilleux, aet bsont des listes. Ils travailleront dans np.dot; mais pas dedans a*b. Si vous utilisez np.array(a)ou np.matrix(a), *fonctionne mais avec des résultats différents.
hpaulj

Réponses:


156

Pour la multiplication élémentaire des matrixobjets, vous pouvez utiliser numpy.multiply:

import numpy as np
a = np.array([[1,2],[3,4]])
b = np.array([[5,6],[7,8]])
np.multiply(a,b)

Résultat

array([[ 5, 12],
       [21, 32]])

Cependant, vous devriez vraiment utiliser à la arrayplace de matrix. matrixles objets ont toutes sortes d'incompatibilités horribles avec les ndarrays ordinaires. Avec ndarrays, vous pouvez simplement utiliser *pour la multiplication élémentaire:

a * b

Si vous utilisez Python 3.5+, vous ne perdez même pas la possibilité d'effectuer une multiplication matricielle avec un opérateur, car @la multiplication matricielle fait maintenant :

a @ b  # matrix multiplication

12
Juste pour ajouter un peu de contexte: en algèbre, cette opération est connue sous le nom de produit Hadamard , et elle est différente du produit matriciel plus courant. en.wikipedia.org/wiki/Hadamard_product_(matrices)
FaCoffee

36

fais juste ceci:

import numpy as np

a = np.array([[1,2],[3,4]])
b = np.array([[5,6],[7,8]])

a * b

1
non, cela donne la multiplication de la matrice. Cloud résolvez-le en utilisant numpy.multiply
Malintha

2
Quelle version et version mineure de Python utilisez-vous? Et de numpy?
smci

1
En utilisant Intel Python 3.5.2 avec numpy 1.12.1, l' *opérateur semble effectuer une multiplication par élément.
apnorton

1
Cela fonctionne aussi pour moi avec Numpy 1.12.1 sur Python 3.5.2 (construit avec gcc).
Autodidacte le

6
@Malintha, je pense que vous faites une = np. ** matrice ** ([[1,2], [3,4]]) à la place
SeF

11
import numpy as np
x = np.array([[1,2,3], [4,5,6]])
y = np.array([[-1, 2, 0], [-2, 5, 1]])

x*y
Out: 
array([[-1,  4,  0],
       [-8, 25,  6]])

%timeit x*y
1000000 loops, best of 3: 421 ns per loop

np.multiply(x,y)
Out: 
array([[-1,  4,  0],
       [-8, 25,  6]])

%timeit np.multiply(x, y)
1000000 loops, best of 3: 457 ns per loop

Les deux np.multiplyet *donneraient une multiplication élémentaire connue sous le nom de produit Hadamard

%timeit est la magie d'ipython


1

Essaye ça:

a = np.matrix([[1,2], [3,4]])
b = np.matrix([[5,6], [7,8]])

#This would result a 'numpy.ndarray'
result = np.array(a) * np.array(b)

Ici, np.array(a)renvoie un tableau 2D de type ndarrayet la multiplication de deux ndarrayentraînerait une multiplication élément par élément. Le résultat serait donc:

result = [[5, 12], [21, 32]]

Si vous voulez obtenir une matrice, faites-le avec ceci:

result = np.mat(result)

Veuillez expliquer ce que cela fait.
Leopold Joy

2
@LeopoldJoy Je viens de modifier ma réponse, j'espère que cela aide :))
Amir Rezazadeh
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.