¿Las matrices numpy 1D siguen las reglas de fila / columna?

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