python numpy ValueError: les opérandes n'ont pas pu être diffusés avec les formes

129

Dans numpy, j'ai deux "tableaux", Xest (m,n)et yest un vecteur(n,1)

en utilisant

X*y

Je reçois l'erreur

ValueError: operands could not be broadcast together with shapes (97,2) (2,1) 

Quand (97,2)x(2,1)est clairement une opération matricielle légale et devrait me donner un (97,1)vecteur

ÉDITER:

J'ai corrigé cela en utilisant X.dot(y)mais la question d'origine demeure.

yayu
la source
2
Quelle est la "question originale"? X*yne devrait pas fonctionner (et cela ne fonctionne pas), mais np.dot(X,y)et X.dot(y))devrait fonctionner (et pour moi, ils le font).
DSM
3
*n'est pas une multiplication matricielle pour les ndarrayobjets.
user2357112 prend en charge Monica le
J'ai rencontré le même problème lors de la résolution de wT * X, alors que cela devrait être np.dot (wT, X)
Juan Zamora
X * y fait une multiplication par élément
Victor Zuanazzi

Réponses:

93

dotest la multiplication matricielle, mais *fait autre chose.

Nous avons deux tableaux:

  • X, forme (97,2)
  • y, forme (2,1)

Avec les tableaux Numpy, l'opération

X * y

est effectué par élément, mais une ou les deux valeurs peuvent être développées dans une ou plusieurs dimensions pour les rendre compatibles. Cette opération s'appelle la diffusion. Les dimensions dont la taille est 1 ou qui manquent peuvent être utilisées en radiodiffusion.

Dans l'exemple ci-dessus, les dimensions sont incompatibles, car:

97   2
 2   1

Ici, il y a des nombres contradictoires dans la première dimension (97 et 2). C'est ce dont la ValueError ci-dessus se plaint. La deuxième dimension serait correcte, car le numéro 1 n'est pas en conflit avec quoi que ce soit.

Pour plus d'informations sur les règles de diffusion: http://docs.scipy.org/doc/numpy/user/basics.broadcasting.html

(Veuillez noter que si Xet ysont de type numpy.matrix, alors l'astérisque peut être utilisé comme multiplication matricielle. Ma recommandation est de rester à l'écart numpy.matrix, cela a tendance à compliquer plus que simplifier les choses.)

Vos tableaux devraient être bien avec numpy.dot; si vous obtenez une erreur numpy.dot, vous devez avoir un autre bogue. Si les formes sont incorrectes numpy.dot, vous obtenez une exception différente:

ValueError: matrices are not aligned

Si vous obtenez toujours cette erreur, veuillez publier un exemple minimal du problème. Un exemple de multiplication avec des tableaux en forme de vôtre réussit:

In [1]: import numpy

In [2]: numpy.dot(numpy.ones([97, 2]), numpy.ones([2, 1])).shape
Out[2]: (97, 1)
DrV
la source
34

Par docs numpy :

Lorsqu'il fonctionne sur deux tableaux, NumPy compare leurs formes élément par élément. Il commence par les dimensions de fin et poursuit son chemin. Deux dimensions sont compatibles lorsque:

  • ils sont égaux, ou
  • l'un d'eux est 1

En d'autres termes, si vous essayez de multiplier deux matrices (dans le sens de l'algèbre linéaire), vous le souhaitez, X.dot(y)mais si vous essayez de diffuser des scalaires de matrice yvers, Xvous devez effectuer X * y.T.

Exemple:

>>> import numpy as np
>>>
>>> X = np.arange(8).reshape(4, 2)
>>> y = np.arange(2).reshape(1, 2)  # create a 1x2 matrix
>>> X * y
array([[0,1],
       [0,3],
       [0,5],
       [0,7]])
gobrewers14
la source
11

Il est possible que l'erreur ne se soit pas produite dans le produit scalaire, mais après. Par exemple, essayez ceci

a = np.random.randn(12,1)
b = np.random.randn(1,5)
c = np.random.randn(5,12)
d = np.dot(a,b) * c

np.dot (a, b) ira bien; cependant np.dot (a, b) * c est clairement faux (12x1 X 1x5 = 12x5 qui ne peut pas multiplier par élément 5x12) mais numpy vous donnera

ValueError: operands could not be broadcast together with shapes (12,1) (1,5)

L'erreur est trompeuse; cependant, il y a un problème sur cette ligne.

Kenan
la source
1
Le message d'erreur est en effet trompeur, car cela semble apparaître lorsque les dimensions de votre matrice sont incorrectes pour la multiplication par élément.
Aung Htet
7

Utilisez np.mat(x) * np.mat(y), cela fonctionnera.

user3101695
la source
7

Vous recherchez np.matmul(X, y). Dans Python 3.5+, vous pouvez utiliser X @ y.

iamanigeeit
la source
0

Nous pourrions nous demander que a * b est un produit scalaire.

Mais en fait, il est diffusé.

Produit scalaire : a.dot (b)

Diffuser:

Le terme diffusion fait référence à la façon dont numpy traite les tableaux de dimensions différentes lors des opérations arithmétiques qui conduisent à certaines contraintes, le plus petit tableau est diffusé sur le plus grand tableau afin qu'ils aient des formes compatibles.

(m, n) + - / * (1, n) → (m, n): l'opération sera appliquée à m lignes

chia yongkang
la source