2012-06-14 13 views
42

¿Cuál es la diferencia entrediferencia entre puntos numpy() e interior()

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

y

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

todos los ejemplos que he intentado devolvió el mismo resultado. Wikipedia tiene el mismo artículo para ambos ?! En the description de inner(), dice, que su comportamiento es diferente en dimensiones más altas, pero no pude producir ningún resultado diferente. ¿Cuál debería usar?

Respuesta

45

numpy.dot:

For 2-D arrays it is equivalent to matrix multiplication, and for 1-D arrays to inner product of vectors (without complex conjugation). For N dimensions it is a sum product over the last axis of a and the second-to-last of b:

numpy.inner:

Ordinary inner product of vectors for 1-D arrays (without complex conjugation), in higher dimensions a sum product over the last axes.

(. Énfasis mío)

Como ejemplo, considere este ejemplo con matrices 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]]) 

Por lo tanto, el que debe usar es el que proporciona el comportamiento correcto para su aplicación.


pruebas de rendimiento

(Nótese que estoy probando sólo el caso 1D, ya que es la única situación en la que .dot y .inner dan el mismo resultado.)

>>> 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] 

Así tal vez .inner es más rápido, pero mi máquina está bastante cargada en este momento, por lo que los tiempos no son consistentes ni son necesariamente muy precisos.

+1

@MillaWell, son diferentes incluso para matrices 2D: son solo las mismas en 1D. No conozco ninguna diferencia de rendimiento, hay dos formas de probar esto: [leer la fuente] (https://github.com/numpy/numpy/blob/master/numpy/core/blasdot/_dotblas.c) (no es fácil) o hacer algunos perfiles con 'timeit' (mucho más fácil). – huon

+1

Creo que, en general, entendí todo. Por ejemplo, en su ejemplo, calcula el primer valor de '.dot' como (1 * 11 + 2 * 13). ¿Cómo calcularías el primer valor de tu ejemplo de '.inner'? –

+2

@MillaWell, tienes razón. Deje 'c = np.dot (a, b)' y 'd = np.inner (a, b)' luego 'c [i, j] == sum (a [i ,:] * b [:, j ]) 'y' d [i, j] == suma (a [i ,:] * b [j,:]) '. – huon

12

np.dot y np.inner son idénticos para matrices de 1 dimensión, por lo que es probable que por eso no note ninguna diferencia. Para arreglos de dimensión N, corresponden a operaciones de tensor comunes.

np.inner a veces se denomina un "producto vectorial" entre un tensor de orden superior e inferior, particularmente un tensor multiplicado por un vector, y a menudo conduce a una "contracción de tensor". Incluye la multiplicación matriz-vector.

np.dot corresponde a un "producto tensor", e incluye el caso mencionado al final de la página de Wikipedia. Generalmente se usa para la multiplicación de dos tensores similares para producir un nuevo tensor. Incluye la multiplicación matriz-matriz.

Si no está utilizando tensores, entonces no necesita preocuparse por estos casos y se comportan de manera idéntica.

+0

Parece que 'np.dot' ahora (es decir, en Python 3) multiplicación de matrices, independientemente de la dimensión. Por lo tanto, es diferente de 'np.inner' incluso para matrices de 1-D. –

+0

Estoy viendo resultados idénticos en NumPy 1.13.3 con Python 3.6.3. Qué versión estás usando? Un ejemplo también sería bueno. –

1

interior no está funcionando correctamente con matrices 2D complejas, trata de multiplicar

y su transpuesta

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]]) 

usted recibirá

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]]) 

multiplicando eficazmente las filas de filas en lugar de filas a las columnas

4

Para matrices de 1 y 2 dimensiones numpy.inne r funciona como transponer la segunda matriz y luego multiplicar. Así que para :

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]) 

trabajé esto con ejemplos como:

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

Esto también explica el comportamiento en una dimensión, numpy.inner([a,b],[c,b]) = ac+bd y numpy.inner([[a],[b]], [[c],[d]]) = [[ac,ad],[bc,bd]]. Este es el grado de mi conocimiento, no tengo idea de lo que hace para las dimensiones más altas.

-1

Hay una gran diferencia entre el producto interno y el producto de punto en el espacio dimensional superior. a continuación se muestra un ejemplo de matriz 2x2 y matriz 3x2 x = [[a1, b1], [c1, d1]] y = [[a2, b2]. [c2, d2], [e2, f2]

np.inner (x, y)

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

Pero en el caso del producto escalar, la salida muestra el siguiente error ya que no se puede multiplicar una matriz de 2x2 con un 3x2.

ValueError: formas (2,2) y (3,2) no alineadas: 2 (DIM 1) = 3 (dim 0)

-2

Simplemente hablando, np.dot da la multiplicación de matrices () wheras np.inner da producto tensor ()

Cuestiones relacionadas