web-dev-qa-db-fra.com

différence entre numpy dot () et inner ()

Quelle est la différence entre

import numpy as np
np.dot(a,b)

et

import numpy as np
np.inner(a,b)

tous les exemples que j'ai essayés ont donné le même résultat. Wikipedia a le même article pour les deux?! Dans la description de inner() il est indiqué que son comportement est différent dans les dimensions supérieures, mais que je ne pouvais pas produire de sortie différente. Lequel devrais-je utiliser? 

46
Milla Well

numpy.dot :

Pour les matrices 2D, cela équivaut à la multiplication matricielle et pour les matrices 1D au produit interne des vecteurs (sans conjugaison complexe). Pour N dimensions, il s’agit d’un produit somme sur le dernier axe de a et le avant-dernier de b:

numpy.inner :

Produit intérieur ordinaire des vecteurs pour les tableaux 1-D (sans conjugaison complexe), dans les dimensions supérieures, un produit somme sur les derniers axes.

(Souligné par moi.)

A titre d'exemple, considérons cet exemple avec des tableaux 2D:

>>> a=np.array([[1,2],[3,4]])
>>> b=np.array([[11,12],[13,14]])
>>> np.dot(a,b)
array([[37, 40],
       [85, 92]])
>>> np.inner(a,b)
array([[35, 41],
       [81, 95]])

Ainsi, celui que vous devriez utiliser est celui qui donne le comportement correct pour votre application.


Test de performance

(Notez que je teste uniquement le cas 1D, car il s'agit du seul cas où .dot et .inner donnent le même résultat.)

>>> import timeit
>>> setup = 'import numpy as np; a=np.random.random(1000); b = np.random.random(1000)'

>>> [timeit.timeit('np.dot(a,b)',setup,number=1000000) for _ in range(3)]
[2.6920320987701416, 2.676928997039795, 2.633111000061035]

>>> [timeit.timeit('np.inner(a,b)',setup,number=1000000) for _ in range(3)]
[2.588860034942627, 2.5845699310302734, 2.6556360721588135]

Donc peut-être que .inner est plus rapide, mais ma machine est assez chargée en ce moment, donc les timings ne sont pas cohérents, ni nécessairement très précis.

51
huon

np.dot et np.inner sont identiques pour les tableaux à une dimension, c'est probablement pourquoi vous ne remarquez aucune différence. Pour les tableaux à N dimensions, ils correspondent aux opérations de tenseur courantes.

np.inner est parfois appelé "produit vectoriel" entre un tenseur d'ordre supérieur et inférieur, en particulier un tenseur fois un vecteur, et conduit souvent à une "contraction du tenseur". Il comprend la multiplication matrice-vecteur.

np.dot correspond à un "produit tensor" et inclut le cas mentionné au bas de la page Wikipedia. Il est généralement utilisé pour la multiplication de deux tenseurs similaires afin de produire un nouveau tenseur. Cela inclut la multiplication matrice-matrice.

Si vous n'utilisez pas de tenseurs, vous n'avez pas à vous soucier de ces cas et ils se comportent de manière identique.

14
marshall.ward

Pour les tableaux à 1 et 2 dimensions, numpy.inner fonctionne comme une transposition de la seconde matrice, puis multiplier . Donc pour:

A = [[a1,b1],[c1,d1]]
B = [[a2,b2],[c2,d2]]
numpy.inner(A,B)
array([[a1*a2 + b1*b2, a1*c2 + b1*d2],
       [c1*a2 + d1*b2, c1*c2 + d1*d2])

J'ai travaillé cela en utilisant des exemples comme:

A=[[1  ,10], [100,1000]]
B=[[1,2], [3,4]]
numpy.inner(A,B)
array([[  21,   43],
       [2100, 4300]])

Cela explique également le comportement dans une dimension, numpy.inner([a,b],[c,b]) = ac+bd et numpy.inner([[a],[b]], [[c],[d]]) = [[ac,ad],[bc,bd]]. C’est l’étendue de mes connaissances, aucune idée de ce qu’il fait pour les dimensions supérieures.

5
Rob McKemey

inner ne fonctionne pas correctement avec les tableaux 2D complexes, essayez de multiplier

et sa transposition

array([[ 1.+1.j,  4.+4.j,  7.+7.j],
       [ 2.+2.j,  5.+5.j,  8.+8.j],
       [ 3.+3.j,  6.+6.j,  9.+9.j]])

tu auras

array([[ 0. +60.j,  0. +72.j,  0. +84.j],
       [ 0.+132.j,  0.+162.j,  0.+192.j],
       [ 0.+204.j,  0.+252.j,  0.+300.j]])

multiplier efficacement les lignes en lignes plutôt que des lignes en colonnes

1
Himanshu

Il y a beaucoup de différence entre le produit interne et le produit scalaire dans un espace dimensionnel supérieur. ci-dessous est un exemple d'une matrice 2x2 et d'une matrice 3x2 x = [[a1, b1], [c1, d1]] y. [[a2, b2]. [c2, d2], [e2, f2]

np.inner (x, y) 

sortie = [[a1xa2 + b1xb2, a1xc2 + b1xd2, a1xe2 + b1f2], [c1xa2 + d1xb2, c1xc2 + d1xd2, c1xe2 + d1xf2]]

Mais dans le cas du produit scalaire, la sortie indique l'erreur ci-dessous car vous ne pouvez pas multiplier une matrice 2x2 par un 3x2.

ValueError: formes (2,2) et (3,2) non alignées: 2 (dim 1)! = 3 (dim 0)

0
pylearner