Estoy haciendo mucho álgebra vectorial y quiero usar matrices numpy para eliminar cualquier necesidad de bucles y correr más rápido.
Lo que encontré es que si tengo una matriz A de tamaño [N,P], necesito usar constantemente np.array([A[:,0]).T para forzar a A[:,0] a ser un vector columna de tamaño (N,1)
¿Hay alguna manera de mantener la fila o columna única de una matriz 2D como una matriz 2D porque hace que la siguiente aritmética sea mucho más fácil? Por ejemplo, a menudo tengo que multiplicar un vector de columna (de una matriz) con un vector de fila (también creado a partir de una matriz) para crear una nueva matriz: por ejemplo
C = A[:,i] * B[j,:]sería genial si no tuviera que seguir usando:
C = np.array([A[:,i]]).T * np.array([B[j,:]]) Realmente ofusca el código: en MATLAB sería simplemente C = A[:,i] * B[j,:] que es más fácil de leer y comparar con las matemáticas subyacentes, especialmente si hay muchos términos como este en la misma línea, pero desafortunadamente la mayoría de mis colegas no tienen licencias de MATLAB.
Tenga en cuenta que este no es el único caso de uso, por lo que una función específica para esta operación de columna x fila no es muy útil
Incluso MATLAB/Octave elimina el exceso de dimensiones:
>> ones(2,3,4)(:,:,1) ans = 1 1 1 1 1 1 >> size(ones(2,3,4)(1,:)) # some indexing "flattens" outer dims ans = 1 12Cuando inicié MATLAB v3.5, la matriz 2d era todo lo que tenía; Las celdas, la estructura y las dimensiones más altas fueron adiciones posteriores (como lo demuestran los ejemplos anteriores).
Su:
In [760]: A=np.arange(6).reshape(2,3) In [762]: np.array([A[:,0]]).T Out[762]: array([[0], [3]])es más complicado de lo necesario. Hace una lista, luego una matriz (1,N) a partir de eso, y finalmente una (N,1)
A[:,[0]] , A[:,:,None] , A[:,0:1] son más directos. Incluso A[:,0].reshape(-1,1)
No puedo pensar en algo simple que trate un índice escalar y de lista de la misma manera.
Funciones como np.atleast_2d pueden agregar condicionalmente una nueva dimensión, pero será una principal (externa). Pero según las reglas de la broadcasting , las dimensiones principales suelen ser "automáticas".
En Python subyacente, los escalares no se pueden indexar y las listas solo se pueden indexar con escalares y segmentos. La sintaxis subyacente permite la indexación con tuplas, pero las listas las rechazan. Es numpy que ha extendido considerablemente la indexación, no con la sintaxis sino con la forma en que maneja esas tuplas.
La indexación numpy con segmentos y escalares es una indexación basic . Ahí es donde puede ocurrir la pérdida de dimensión. Eso es consistente con la indexación de listas.
In [768]: [[1,2,3],[4,5,6]][1] Out[768]: [4, 5, 6] In [769]: np.array([[1,2,3],[4,5,6]])[1] Out[769]: array([4, 5, 6]) La indexación con listas y matrices es una indexación advanced , sin ninguna contraparte de lista. Aquí es quizás donde las diferencias entre MATLAB y numpy son más feas :)
>> A([1,2],[1,2])produce un bloque (2,2). En numpy que produce una "diagonal"
In [781]: A[[0,1],[0,1]] Out[781]: array([0, 4])Para obtener el bloque, tenemos que usar listas (o matrices) que se "transmiten" entre sí:
In [782]: A[[[0],[1]],[0,1]] Out[782]: array([[0, 1], [3, 4]]) Para obtener la "diagonal" en MATLAB tenemos que usar sub2ind([2,2],[1,2],[1,2]) para obtener los índices planos [1,4].
En
np.array([A[:,i]]).T * np.array([B[j,:]]) ¿Es esto por elementos ( .* ) o matriz?
Para un par (N,1) y (1,M), A*B y A@B producen el mismo resultado (N,M), pero uno utiliza la broadcasting para generalizar el producto outer y el otro es el producto interior/matriz. (con suma de productos).
https://numpy.org/doc/stable/reference/generated/numpy.matrix.html
Devuelve una matriz de un objeto similar a una matriz o de una cadena de datos. Una matriz es una matriz bidimensional especializada que conserva su naturaleza bidimensional a través de operaciones . Tiene ciertos operadores especiales, como * (multiplicación de matriz) y ** (potencia de matriz).
Sin embargo, no estoy seguro de cómo volver a implementarlo, es un ejercicio interesante.
Como se mencionó, matrix quedará en desuso. Pero desde np.array, puede especificar la dimensión con el argumento ndim=2:
np.array([1, 2, 3], ndmin=2)Puede mantener la dimensión de la siguiente manera (usando @ para la multiplicación de matrices)
C = A[:,[i]] @ B[[j],:] Observe los corchetes alrededor de i y j , de lo contrario, C no será una matriz bidimensional.