Prefacio del traductor
Hola de nuevo Continuando con nuestra serie de artículos sobre la traducción de mana sobre numpy. Que tengas una buena lectura.
Operadores de comparación y pruebas de valor
La comparación booleana se puede usar para la comparación por elementos de matrices de la misma longitud. El valor de retorno es una matriz de valores booleanos verdadero / falso:
>>> a = np.array([1, 3, 0], float) >>> b = np.array([0, 3, 2], float) >>> a > b array([ True, False, False], dtype=bool) >>> a == b array([False, True, False], dtype=bool) >>> a <= b array([False, True, True], dtype=bool)
El resultado de la comparación se puede almacenar en una matriz:
>>> c = a > b >>> c array([ True, False, False], dtype=bool)
Las matrices se pueden comparar con un solo valor:
>>> a = np.array([1, 3, 0], float) >>> a > 2 array([False, True, False], dtype=bool)
Los operadores any y all pueden usarse para determinar si al menos uno o todos los elementos son verdaderos, respectivamente:
>>> c = np.array([ True, False, False], bool) >>> any(c) True >>> all(c) False
Las expresiones booleanas combinadas se pueden aplicar a las matrices elemento por elemento utilizando las funciones especiales logical_and, logical_or y logical_not:
>>> a = np.array([1, 3, 0], float) >>> np.logical_and(a > 0, a < 3) array([ True, False, False], dtype=bool) >>> b = np.array([True, False, True], bool) >>> np.logical_not(b) array([False, True, False], dtype=bool) >>> c = np.array([False, True, False], bool) >>> np.logical_or(b, c) array([ True, True, False], dtype=bool)
La función where crea una nueva matriz a partir de otras dos matrices de la misma longitud utilizando un filtro booleano para seleccionar entre dos elementos. Sintaxis básica: where (boolarray,
truearray, falsearray):
>>> a = np.array([1, 3, 0], float) >>> np.where(a != 0, 1 / a, a) array([ 1. , 0.33333333, 0. ])
Con la función where, la comparación de masas también se puede implementar:
>>> np.where(a > 0, 3, 2) array([3, 3, 2])
Algunas funciones permiten probar valores en una matriz. La función distinta de cero devuelve una tupla de índices de valores distintos de cero. El número de elementos en la tupla es igual al número de ejes en la matriz:
>>> a = np.array([[0, 1], [3, 0]], float) >>> a.nonzero() (array([0, 1]), array([1, 0]))
También puede verificar los valores de finitud y NaN (no un número):
>>> a = np.array([1, np.NaN, np.Inf], float) >>> a array([ 1., NaN, Inf]) >>> np.isnan(a) array([False, True, False], dtype=bool) >>> np.isfinite(a) array([ True, False, False], dtype=bool)
Aunque usamos constantes numpy aquí para agregar NaN e infinito, pueden ser el resultado de aplicar operaciones matemáticas estándar.
Seleccionar y manipular elementos de matriz
Ya hemos visto, al igual que con las listas, que se pueden obtener elementos de la matriz utilizando la operación de acceso por índice. Sin embargo, a diferencia de las listas, las matrices también le permiten seleccionar elementos utilizando otras matrices. Esto significa que podemos usar una matriz para filtrar subconjuntos específicos de los elementos de otras matrices.
Las matrices booleanas se pueden usar como matrices para filtrar:
>>> a = np.array([[6, 4], [5, 9]], float) >>> a >= 6 array([[ True, False], [False, True]], dtype=bool) >>> a[a >= 6] array([ 6., 9.])
Vale la pena señalar que cuando pasamos una matriz booleana a> = 6 como índice para la operación de acceso por el índice de la matriz a, la matriz devuelta solo almacenará valores verdaderos. También podemos escribir una matriz para filtrar en una variable:
>>> a = np.array([[6, 4], [5, 9]], float) >>> sel = (a >= 6) >>> a[sel] array([ 6., 9.])
Se puede lograr un filtrado más sofisticado utilizando expresiones booleanas:
>>> a[np.logical_and(a > 5, a < 9)] >>> array([ 6.])
Además de la selección booleana, también puede usar matrices de enteros. En este caso, la matriz entera almacena los índices de los elementos que se tomarán de la matriz. Considere el siguiente ejemplo unidimensional:
>>> a = np.array([2, 4, 6, 8], float) >>> b = np.array([0, 0, 1, 3, 2, 1], int) >>> a[b] array([ 2., 2., 4., 8., 6., 4.])
En otras palabras, cuando usamos b para obtener los elementos de a, tomamos los elementos 0, 0, 1, 3, 2 y 1 de a en este orden. Las listas también se pueden usar como matrices para el filtrado:
>>> a = np.array([2, 4, 6, 8], float) >>> a[[0, 0, 1, 3, 2, 1]] array([ 2., 2., 4., 8., 6., 4.])
Para las matrices multidimensionales, necesitamos transferir varias matrices enteras unidimensionales al índice del operador de acceso (
traductor de notas: en nuestro caso, los índices son matrices ) para cada eje. Luego, cada una de las matrices pasa por la siguiente secuencia: el primer elemento corresponde al índice de la fila, que es el primer elemento de la matriz b, el segundo elemento corresponde al índice de la columna, que es el primer elemento de la matriz c, y así sucesivamente. (
Nota del traductor: la primera matriz [2, 2] y la segunda [1, 4], tenemos elementos con los índices [2, 1] y [2, 4] en la salida ) Ejemplo:
>>> a = np.array([[1, 4], [9, 16]], float) >>> b = np.array([0, 0, 1, 1, 0], int) >>> c = np.array([0, 1, 1, 1, 1], int) >>> a[b,c] array([ 1., 4., 16., 16., 4.])
Una función de toma especial está disponible para buscar con matrices de enteros. Esto funciona igual que usar el operador take en un índice:
>>> a = np.array([2, 4, 6, 8], float) >>> b = np.array([0, 0, 1, 3, 2, 1], int) >>> a.take(b) array([ 2., 2., 4., 8., 6., 4.])
La función take también proporciona el argumento del eje para tomar una subsección de la matriz multidimensional a lo largo de un eje. (
Nota traductor: fila o columna (para matrices bidimensionales) ).
>>> a = np.array([[0, 1], [2, 3]], float) >>> b = np.array([0, 0, 1], int) >>> a.take(b, axis=0) array([[ 0., 1.], [ 0., 1.], [ 2., 3.]]) >>> a.take(b, axis=1) array([[ 0., 0., 1.], [ 2., 2., 3.]])
A diferencia de la función take, hay una función put, que tomará valores de la matriz original y los escribirá en índices específicos en otra matriz put.
>>> a = np.array([0, 1, 2, 3, 4, 5], float) >>> b = np.array([9, 8, 7], float) >>> a.put([0, 3], b) >>> a array([ 9., 1., 2., 8., 4., 5.])
Tenga en cuenta que el valor 7 de la matriz original b no se usó, ya que solo se indican 2 índices [0, 3]. La matriz original se repetirá si es necesario si las longitudes no coinciden:
>>> a = np.array([0, 1, 2, 3, 4, 5], float) >>> a.put([0, 3], 5) >>> a array([ 5., 1., 2., 5., 4., 5.])
Matemáticas vectoriales y matriciales
NumPy proporciona muchas funciones para trabajar con vectores y matrices. La función punto devuelve el producto escalar de vectores:
>>> a = np.array([1, 2, 3], float) >>> b = np.array([0, 1, 1], float) >>> np.dot(a, b) 5.0
La función punto también puede multiplicar matrices:
>>> a = np.array([[0, 1], [2, 3]], float) >>> b = np.array([2, 3], float) >>> c = np.array([[1, 1], [4, 0]], float) >>> a array([[ 0., 1.], [ 2., 3.]]) >>> np.dot(b, a) array([ 6., 11.]) >>> np.dot(a, b) array([ 3., 13.]) >>> np.dot(a, c) array([[ 4., 0.], [ 14., 2.]]) >>> np.dot(c, a) array([[ 2., 4.], [ 0., 4.]])
También puede obtener el producto escalar, tensor y externo de matrices y vectores. Tenga en cuenta que para los vectores el producto interno y el escalar coinciden.
>>> a = np.array([1, 4, 0], float) >>> b = np.array([2, 2, 1], float) >>> np.outer(a, b) array([[ 2., 2., 1.], [ 8., 8., 4.], [ 0., 0., 0.]]) >>> np.inner(a, b) 10.0 >>> np.cross(a, b) array([ 4., -1., -6.])
NumPy también proporciona un conjunto de funciones y métodos integrados para trabajar con álgebra lineal. Todo esto se puede encontrar en el submódulo linalg. Estos módulos también se pueden operar con matrices degeneradas y no degeneradas. El determinante de la matriz se busca de esta manera:
>>> a = np.array([[4, 2, 0], [9, 3, 7], [1, 2, 1]], float) >>> a array([[ 4., 2., 0.], [ 9., 3., 7.], [ 1., 2., 1.]]) >>> np.linalg.det(a) -48.
También puede encontrar el vector propio y el valor propio de la matriz:
>>> vals, vecs = np.linalg.eig(a) >>> vals array([ 9. , 2.44948974, -2.44948974]) >>> vecs array([[-0.3538921 , -0.56786837, 0.27843404], [-0.88473024, 0.44024287, -0.89787873], [-0.30333608, 0.69549388, 0.34101066]])
Una matriz no degenerada se puede encontrar de la siguiente manera:
>>> b = np.linalg.inv(a) >>> b array([[ 0.14814815, 0.07407407, -0.25925926], [ 0.2037037 , -0.14814815, 0.51851852], [-0.27777778, 0.11111111, 0.11111111]]) >>> np.dot(a, b) array([[ 1.00000000e+00, 5.55111512e-17, 2.22044605e-16], [ 0.00000000e+00, 1.00000000e+00, 5.55111512e-16], [ 1.11022302e-16, 0.00000000e+00, 1.00000000e+00]])
Se puede lograr una descomposición única (un análogo de la diagonalización de una matriz no cuadrada) de la siguiente manera:
>>> a = np.array([[1, 3,4], [5, 2, 3]], float) >>> U, s, Vh = np.linalg.svd(a) >>> U array([[-0.6113829 , -0.79133492], [-0.79133492, 0.6113829 ]]) >>> s array([ 7.46791327, 2.86884495]) >>> Vh array([[-0.61169129, -0.45753324, -0.64536587], [ 0.78971838, -0.40129005, -0.46401635], [-0.046676 , -0.79349205, 0.60678804]])
Terminamos la tercera parte. Buena suerte y hasta pronto!