Acabo de empezar a usar numpy y me estoy confundiendo acerca de cómo usar arreglos. He visto varias respuestas de desbordamiento de stack en matrices numpy pero todas tratan sobre cómo obtener el resultado deseado (sé cómo hacerlo, pero no sé por qué tengo que hacerlo de esta manera). El consenso que he visto es que las matrices son mejores que las matrices porque son una clase más básica y menos restrictiva. Entiendo que puede transponer una matriz, lo que para mí significa que hay una distinción entre una fila y una columna, pero todas las reglas de multiplicación producen resultados erróneos (en comparación con lo que estoy esperando).
Aquí está el código de prueba que he escrito junto con las salidas:
a = numpy.array([1,2,3,4]) print(a) >>> [1 2 3 4] print(aT) # Transpose >>> [1 2 3 4] # No apparent affect b = numpy.array( [ [1], [2], [3], [4] ] ) print(b) >>> [[1] [2] [3] [4]] # Column (Expected) print(bT) >>> [[1 2 3 4]] # Row (Expected, transpose seems to work here) print((bT).T) >>> [[1] [2] [3] [4]] # Column (All of these are as expected, # unlike for declaring the array as a row vector) # The following are element wise multiplications of a print(a*a) >>> [ 1 4 9 16] print(a * aT) # Row*Column >>> [ 1 4 9 16] # Inner product scalar result expected print(aT * a) # Column*Row >>> [ 1 4 9 16] # Outer product matrix result expected print(b*b) >>> [[1] [4] [9] [16]] # Expected result, element wise multiplication in a column print(b * bT) # Column * Row (Outer product) >>> [[ 1 2 3 4] [ 2 4 6 8] [ 3 6 9 12] [ 4 8 12 16]] # Expected matrix result print(bT * (bT)) # Column * Column (Doesn't make much sense so I expected elementwise multiplication >>> [[ 1 4 9 16]] print(bT * (bT).T) # Row * Column, inner product expected >>> [[ 1 2 3 4] [ 2 4 6 8] [ 3 6 9 12] [ 4 8 12 16]] # Outer product result
Sé que puedo usar numpy.inner()
y numpy.outer()
para lograr el efecto (eso no es un problema), solo quiero saber si debo hacer un seguimiento de si mis vectores son filas o columnas.
También sé que puedo crear una matriz 1D para representar mis vectores y la multiplicación funciona como se esperaba. Estoy tratando de encontrar la mejor manera de almacenar mis datos para que cuando vea mi código quede claro lo que va a suceder, en este momento las matemáticas solo parecen confusas e incorrectas.
Solo necesito usar tensores 1D y 2D para mi aplicación.
Intentaré anotar tu código
a = numpy.array([1,2,3,4]) print(a) >>> [1 2 3 4] print(aT) # Transpose >>> [1 2 3 4] # No apparent affect
a.shape
mostrará (4,)
. aTshape
es lo mismo. Mantuvo el mismo número de dimensiones y realizó la única transposición significativa, sin cambios. Hacerlo (4,1)
hubiera agregado una dimensión y destruido el ATT
ida y vuelta de ATT
.
b = numpy.array( [ [1], [2], [3], [4] ] ) print(b) >>> [[1] [2] [3] [4]] # Column (Expected) print(bT) >>> [[1 2 3 4]] # Row (Expected, transpose seems to work here)
b.shape
es (4,1)
, bTshape
es (1,4)
. Tenga en cuenta el conjunto adicional de []. Si hubiera creado a
como a = numpy.array([[1,2,3,4]])
su forma también habría sido (1,4)
.
La manera fácil de hacer b
sería b=np.array([[1,2,3,4]]).T
(o b=np.array([1,2,3,4])[:,None]
o b=np.array([1,2,3,4]).reshape(-1,1)
)
Compara esto con MATLAB
octave:3> a=[1,2,3,4] a = 1 2 3 4 octave:4> size(a) ans = 1 4 octave:5> size(a.') ans = 4 1
Incluso sin el extra [] se ha inicializado la matriz como 2d.
numpy
tiene una clase de matrix
que imita a MATLAB – en el tiempo en que MATLAB solo permitía 2d.
In [75]: m=np.matrix('1 2 3 4')
En [76]: m Fuera [76]: matriz ([[1, 2, 3, 4]])
In [77]: m.shape Out[77]: (1, 4) In [78]: m=np.matrix('1 2; 3 4') In [79]: m Out[79]: matrix([[1, 2], [3, 4]])
No recomiendo usar np.matrix
menos que realmente agregue algo útil a su código.
Tenga en cuenta las conversaciones de vectors
de MATLAB, pero en realidad son solo su matrix
con una sola dimensión no unitaria.
# The following are element wise multiplications of a print(a*a) >>> [ 1 4 9 16] print(a * aT) # Row*Column >>> [ 1 4 9 16] # Inner product scalar result expected
Este comportamiento se sigue de aT == A
Como notaste, *
produce multiplicación elemento por elemento. Esto es equivalente al MATLAB .*
. np.dot(a,a)
proporciona el producto de punto o matriz de 2 matrices.
print(aT * a) # Column*Row >>> [ 1 4 9 16] # Outer product matrix result expected
No, todavía está haciendo la multiplicación elementwise.
Usaría broadcasting
, a[:,None]*a[None,:]
para obtener el producto externo. Octave agregó esto en imitación de numpy; No sé si MATLAB lo tiene todavía.
En lo siguiente: *
es siempre la multiplicación elemento por elemento. Es una transmisión que produce resultados de matriz / producto externo.
print(b*b) >>> [[1] [4] [9] [16]] # Expected result, element wise multiplication in a column
A (4,1) * (4,1)=>(4,1)
. Las mismas formas alrededor.
print(b * bT) # Column * Row (Outer product) >>> [[ 1 2 3 4] [ 2 4 6 8] [ 3 6 9 12] [ 4 8 12 16]] # Expected matrix result
Aquí (4,1)*(1,4)=>(4,4)
producto. Las 2 dimensiones del tamaño 1
se han replicado para que se convierta, efectivamente, en (4,4)*(4,4)
. ¿Cómo replicaría esto en MATLAB – con .*
?
print(bT * (bT)) # Column * Column (Doesn't make much sense so I expected elementwise multiplication >>> [[ 1 4 9 16]]
*
Es elementely independientemente de las expectativas. Piensa b' .* b'
en MATLAB.
print(bT * (bT).T) # Row * Column, inner product expected >>> [[ 1 2 3 4] [ 2 4 6 8] [ 3 6 9 12] [ 4 8 12 16]] # Outer product result
De nuevo *
es elementwise; inner
requiere una sum además de la multiplicación. Aquí se aplica nuevamente la transmisión (1,4)*(4,1)=>(4,4)
.
np.dot(b,b)
o np.trace(bT*b)
o np.sum(b*b)
dan 30
.
Cuando trabajé en MATLAB, verifiqué frecuentemente el size
y creé matrices de prueba que podrían detectar desajustes en las dimensiones (por ejemplo, una matriz 2×3 en lugar de una matriz 2×2). Continúo haciendo eso en cantidad.
Las cosas clave son:
numpy
matrices numpy
pueden ser 1d (o incluso 0d)
Una matriz (4) no es exactamente igual a (4,1)
o (1,4) `.
*
es elementwise – siempre.
La radiodifusión generalmente explica outer
comportamiento outer
“Transposición” es, desde una perspectiva numpy, realmente solo un concepto significativo para estructuras bidimensionales:
>>> import numpy >>> arr = numpy.array([1,2,3,4]) >>> arr.shape (4,) >>> arr.transpose().shape (4,)
Entonces, si quieres transponer algo, tendrás que hacerlo bidimensional:
>>> arr_2d = arr.reshape((4,1)) ## four rows, one column -> two-dimensional >>> arr_2d.shape (4, 1) >>> arr_2d.transpose().shape (1, 4)
Además, numpy.array(iterable, **kwargs)
tiene un argumento de palabra clave ndmin
, que, establecido en ndmin=2
antepondrá la forma deseada con la cantidad necesaria de 1
:
>>> arr_ndmin = numpy.array([1,2,3,4],ndmin=2) >>> arr_ndmin.shape (1, 4)
Ellos si.
Tu pregunta ya está contestada. ¿Aunque asumo que eres un usuario de Matlab? Si es así, puede encontrar útil esta guía: Pasar de matrices de MATLAB a matrices NumPy