En numpy
, algunas de las operaciones vuelven en forma (R, 1)
pero algunas vuelven (R,)
. Esto hará que la multiplicación de matrices sea más tediosa ya que reshape
se requiere explícito . Por ejemplo, dada una matriz M
, si queremos hacer numpy.dot(M[:,0], numpy.ones((1, R)))
dónde R
está el número de filas (por supuesto, el mismo problema también ocurre en forma de columna). Obtendremos un matrices are not aligned
error ya que M[:,0]
está en forma (R,)
pero numpy.ones((1, R))
está en forma (1, R)
.
Entonces mis preguntas son:
¿Cuál es la diferencia entre forma
(R, 1)
y(R,)
. Sé literalmente que es una lista de números y una lista de listas donde toda lista contiene solo un número. Solo me pregunto por qué no diseñarnumpy
para que favorezca la forma en(R, 1)
lugar de(R,)
una multiplicación de matriz más fácil.¿Hay mejores formas para el ejemplo anterior? Sin explícitamente remodelar así:
numpy.dot(M[:,0].reshape(R, 1), numpy.ones((1, R)))
Respuestas:
1. El significado de las formas en NumPy
Usted escribe: "Sé, literalmente, que es una lista de números y una lista de listas donde todas las listas contienen solo un número", pero esa es una forma poco útil de pensarlo.
La mejor manera de pensar sobre las matrices NumPy es que consisten en dos partes, un búfer de datos que es solo un bloque de elementos sin procesar y una vista que describe cómo interpretar el búfer de datos.
Por ejemplo, si creamos una matriz de 12 enteros:
Luego
a
consiste en un búfer de datos, organizado de esta manera:y una vista que describe cómo interpretar los datos:
Aquí la forma
(12,)
significa que la matriz está indexada por un único índice que va de 0 a 11. Conceptualmente, si etiquetamos este índice únicoi
, la matriz sea
ve así:Si reformamos una matriz, esto no cambia el búfer de datos. En cambio, crea una nueva vista que describe una forma diferente de interpretar los datos. Así que después:
la matriz
b
tiene el mismo búfer de datos quea
, pero ahora está indexada por dos índices que se ejecutan de 0 a 2 y de 0 a 3 respectivamente. Si etiquetamos los dos índicesi
yj
, la matriz seb
ve así:Lo que significa que:
Puede ver que el segundo índice cambia rápidamente y el primer índice cambia lentamente. Si prefiere que esto sea al revés, puede especificar el
order
parámetro:lo que resulta en una matriz indexada de esta manera:
Lo que significa que:
Ahora debería quedar claro lo que significa que una matriz tenga una forma con una o más dimensiones de tamaño 1. Después:
la matriz
d
está indexada por dos índices, el primero de los cuales va de 0 a 11, y el segundo índice siempre es 0:y entonces:
Una dimensión de longitud 1 es "gratuita" (en cierto sentido), por lo que no hay nada que te impida ir a la ciudad:
dando una matriz indexada así:
y entonces:
Ver el documentación interna de NumPy para obtener más detalles sobre cómo se implementan las matrices.
2. ¿Qué hacer?
Ya que
numpy.reshape
solo crea una nueva vista, no debe tener miedo de usarla siempre que sea necesario. Es la herramienta adecuada para usar cuando desea indexar una matriz de una manera diferente.Sin embargo, en un cálculo largo, generalmente es posible organizar la construcción de matrices con la forma "correcta" en primer lugar, y así minimizar el número de formas y transposiciones. Pero sin ver el contexto real que llevó a la necesidad de una reforma, es difícil decir qué se debe cambiar.
El ejemplo en su pregunta es:
Pero esto no es realista. Primero, esta expresión:
calcula el resultado de manera más simple. Segundo, ¿hay realmente algo especial en la columna 0? Quizás lo que realmente necesitas es:
fuente
newaxis
si necesita otro eje, por ejemplo,a[:, j, np.newaxis]
es laj
columna tha
ya[np.newaxis, i]
es lai
fila th.(R, )
caso, la forma de landarray
es una tupla con elementos individuales, por lo que Python lo imprime con una coma final. Sin la coma adicional, sería ambiguo con una expresión entre paréntesis . Andarray
con una sola dimensión puede considerarse como un vector de columna de longitudR
. En el(R, 1)
caso, la tupla tiene dos elementos, por lo que puede considerarse como un vector de fila (o una matriz con 1 fila de longitudR
.)La diferencia entre
(R,)
y(1,R)
es literalmente la cantidad de índices que necesita usar.ones((1,R))
es una matriz bidimensional que tiene solo una fila.ones(R)
es un vector En general, si no tiene sentido que la variable tenga más de una fila / columna, debería usar un vector, no una matriz con una dimensión de un solo tono.Para su caso específico, hay un par de opciones:
1) Simplemente haga que el segundo argumento sea un vector. Lo siguiente funciona bien:
2) Si desea operaciones de matriz como matlab, use la clase en
matrix
lugar dendarray
. Todas las matrices se ven obligadas a ser matrices en 2-D, y el operador*
realiza la multiplicación de matrices en lugar de las de elementos (por lo que no necesita puntos). En mi experiencia, esto es más problema de lo que vale, pero puede ser bueno si estás acostumbrado a matlab.fuente
matrix
clase. ¿Cuál es el problema para lamatrix
clase BTW?matrix
es que es solo 2D, y también porque sobrecarga al operador '*', las funciones escritasndarray
pueden fallar si se usan en amatrix
.La forma es una tupla. Si solo hay 1 dimensión, la forma será un número y solo en blanco después de una coma. Para 2+ dimensiones, habrá un número después de todas las comas.
fuente
Para su clase de matriz base, las matrices 2d no son más especiales que las de 1d o 3d. Hay algunas operaciones que preservan las dimensiones, algunas que las reducen, otras las combinan o incluso las expanden.
Otras expresiones que dan la misma matriz
MATLAB comenzó con solo matrices 2D. Las versiones más nuevas permiten más dimensiones, pero conservan el límite inferior de 2. Pero aún debe prestar atención a la diferencia entre una matriz de fila y una columna, una con forma
(1,3)
v(3,1)
. ¿Con qué frecuencia has escrito[1,2,3].'
? Iba a escribirrow vector
ycolumn vector
, pero con esa restricción 2d, no hay vectores en MATLAB, al menos no en el sentido matemático del vector como 1d.¿Has mirado
np.atleast_2d
(también versiones _1d y _3d)?fuente
1) La razón para no preferir una forma de
(R, 1)
sobre(R,)
es que complica innecesariamente las cosas. Además, ¿por qué sería preferible tener forma(R, 1)
por defecto para un vector de longitud R en lugar de(1, R)
? Es mejor mantenerlo simple y ser explícito cuando requiera dimensiones adicionales.2) Para su ejemplo, está calculando un producto externo para que pueda hacer esto sin una
reshape
llamada usandonp.outer
:fuente
M[:,0]
esencialmente obtiene todas las filas con el primer elemento, por lo que tiene más sentido tener(R, 1)
que(1, R)
. 2) No siempre se puede reemplazar pornp.outer
, por ejemplo, punto para matriz en forma (1, R) y luego (R, 1).matrix
objeto. 2) En realidad,np.outer
funciona independientemente de si las formas son(1, R)
,(R, 1)
o una combinación de los dos.Ya hay muchas buenas respuestas aquí. Pero para mí fue difícil encontrar algún ejemplo, donde la forma o la matriz pueden romper todo el programa.
Así que aquí está el uno:
Esto fallará con el error:
pero si agregamos
reshape
aa
:esto funciona correctamente!
fuente