Buscar..
Introducción
Las matrices de N-dimensional o ndarrays
son el objeto central de numpy utilizado para almacenar elementos del mismo tipo de datos. Proporcionan una estructura de datos eficiente que es superior a las matrices comunes de Python.
Observaciones
Siempre que sea posible, exprese operaciones sobre datos en términos de matrices y operaciones vectoriales. Las operaciones vectoriales se ejecutan mucho más rápido que el equivalente para los bucles.
Crear una matriz
Matriz vacía
np.empty((2,3))
Tenga en cuenta que, en este caso, los valores de esta matriz no están establecidos. Esta forma de crear una matriz, por lo tanto, solo es útil si la matriz se llena más adelante en el código.
De una lista
np.array([0,1,2,3])
# Out: array([0, 1, 2, 3])
Crear un rango
np.arange(4)
# Out: array([0, 1, 2, 3])
Crear ceros
np.zeros((3,2))
# Out:
# array([[ 0., 0.],
# [ 0., 0.],
# [ 0., 0.]])
Crear unos
np.ones((3,2))
# Out:
# array([[ 1., 1.],
# [ 1., 1.],
# [ 1., 1.]])
Crear elementos de matriz espaciados lineales
np.linspace(0,1,21)
# Out:
# array([ 0. , 0.05, 0.1 , 0.15, 0.2 , 0.25, 0.3 , 0.35, 0.4 ,
# 0.45, 0.5 , 0.55, 0.6 , 0.65, 0.7 , 0.75, 0.8 , 0.85,
# 0.9 , 0.95, 1. ])
Crear elementos de matriz espaciados por registro
np.logspace(-2,2,5)
# Out:
# array([ 1.00000000e-02, 1.00000000e-01, 1.00000000e+00,
# 1.00000000e+01, 1.00000000e+02])
Crear una matriz a partir de una función dada
np.fromfunction(lambda i: i**2, (5,))
# Out:
# array([ 0., 1., 4., 9., 16.])
np.fromfunction(lambda i,j: i**2, (3,3))
# Out:
# array([[ 0., 0., 0.],
# [ 1., 1., 1.],
# [ 4., 4., 4.]])
Operadores de matrices
x = np.arange(4)
x
#Out:array([0, 1, 2, 3])
la adición escalar es un elemento sabio
x+10
#Out: array([10, 11, 12, 13])
la multiplicación escalar es un elemento sabio
x*2
#Out: array([0, 2, 4, 6])
la suma de matrices es un elemento sabio
x+x
#Out: array([0, 2, 4, 6])
la multiplicación de matrices es un elemento sabio
x*x
#Out: array([0, 1, 4, 9])
El producto puntual (o más generalmente la multiplicación de matrices) se realiza con una función.
x.dot(x)
#Out: 14
En Python 3.5, el operador @
se agregó como operador de infijo para la multiplicación de matrices
x = np.diag(np.arange(4))
print(x)
'''
Out: array([[0, 0, 0, 0],
[0, 1, 0, 0],
[0, 0, 2, 0],
[0, 0, 0, 3]])
'''
print(x@x)
print(x)
'''
Out: array([[0, 0, 0, 0],
[0, 1, 0, 0],
[0, 0, 4, 0],
[0, 0, 0, 9]])
'''
Anexar Devuelve copia con los valores adjuntos. Fuera de lugar.
#np.append(array, values_to_append, axis=None)
x = np.array([0,1,2,3,4])
np.append(x, [5,6,7,8,9])
# Out: array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
x
# Out: array([0, 1, 2, 3, 4])
y = np.append(x, [5,6,7,8,9])
y
# Out: array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
hstack Pila horizontal. (pila de columnas)
Vack Pila vertical. (pila de filas)
# np.hstack(tup), np.vstack(tup)
x = np.array([0,0,0])
y = np.array([1,1,1])
z = np.array([2,2,2])
np.hstack(x,y,z)
# Out: array([0, 0, 0, 1, 1, 1, 2, 2, 2])
np.vstack(x,y,z)
# Out: array([[0, 0, 0],
# [1, 1, 1],
# [2, 2, 2]])
Acceso a Array
La sintaxis de división es i:j:k
donde i
es el índice de inicio (incluido), j
es el índice de detención (exclusivo) y k
es el tamaño del paso. Al igual que otras estructuras de datos de Python, el primer elemento tiene un índice de 0:
x = np.arange(10)
x[0]
# Out: 0
x[0:4]
# Out: array([0, 1, 2, 3])
x[0:4:2]
# Out:array([0, 2])
Los valores negativos cuentan desde el final de la matriz. -1
por lo tanto accede al último elemento en una matriz:
x[-1]
# Out: 9
x[-1:0:-1]
# Out: array([9, 8, 7, 6, 5, 4, 3, 2, 1])
Se puede acceder a las matrices multidimensionales especificando cada dimensión separada por comas. Se aplican todas las reglas anteriores.
x = np.arange(16).reshape((4,4))
x
# Out:
# array([[ 0, 1, 2, 3],
# [ 4, 5, 6, 7],
# [ 8, 9, 10, 11],
# [12, 13, 14, 15]])
x[1,1]
# Out: 5
x[0:3,0]
# Out: array([0, 4, 8])
x[0:3, 0:3]
# Out:
# array([[ 0, 1, 2],
# [ 4, 5, 6],
# [ 8, 9, 10]])
x[0:3:2, 0:3:2]
# Out:
# array([[ 0, 2],
# [ 8, 10]])
Transponiendo una matriz
arr = np.arange(10).reshape(2, 5)
Utilizando el método .transpose
:
arr.transpose()
# Out:
# array([[0, 5],
# [1, 6],
# [2, 7],
# [3, 8],
# [4, 9]])
.T
método:
arr.T
# Out:
# array([[0, 5],
# [1, 6],
# [2, 7],
# [3, 8],
# [4, 9]])
O np.transpose
:
np.transpose(arr)
# Out:
# array([[0, 5],
# [1, 6],
# [2, 7],
# [3, 8],
# [4, 9]])
En el caso de una matriz bidimensional, esto es equivalente a una transposición de matriz estándar (como se muestra arriba). En el caso de n dimensiones, puede especificar una permutación de los ejes de matriz. Por defecto, esto invierte array.shape
:
a = np.arange(12).reshape((3,2,2))
a.transpose() # equivalent to a.transpose(2,1,0)
# Out:
# array([[[ 0, 4, 8],
# [ 2, 6, 10]],
#
# [[ 1, 5, 9],
# [ 3, 7, 11]]])
Pero cualquier permutación de los índices de eje es posible:
a.transpose(2,0,1)
# Out:
# array([[[ 0, 2],
# [ 4, 6],
# [ 8, 10]],
#
# [[ 1, 3],
# [ 5, 7],
# [ 9, 11]]])
a = np.arange(24).reshape((2,3,4)) # shape (2,3,4)
a.transpose(2,0,1).shape
# Out:
# (4, 2, 3)
Indexación booleana
arr = np.arange(7)
print(arr)
# Out: array([0, 1, 2, 3, 4, 5, 6])
La comparación con un escalar devuelve una matriz booleana:
arr > 4
# Out: array([False, False, False, False, False, True, True], dtype=bool)
Esta matriz se puede usar en la indexación para seleccionar solo los números mayores de 4:
arr[arr>4]
# Out: array([5, 6])
La indexación booleana se puede utilizar entre diferentes matrices (por ejemplo, matrices paralelas relacionadas):
# Two related arrays of same length, i.e. parallel arrays
idxs = np.arange(10)
sqrs = idxs**2
# Retrieve elements from one array using a condition on the other
my_sqrs = sqrs[idxs % 2 == 0]
print(my_sqrs)
# Out: array([0, 4, 16, 36, 64])
Remodelando una matriz
El numpy.reshape
(igual que numpy.ndarray.reshape
) devuelve una matriz del mismo tamaño total, pero en una nueva forma:
print(np.arange(10).reshape((2, 5)))
# [[0 1 2 3 4]
# [5 6 7 8 9]]
Devuelve una nueva matriz y no funciona en su lugar:
a = np.arange(12)
a.reshape((3, 4))
print(a)
# [ 0 1 2 3 4 5 6 7 8 9 10 11]
Sin embargo, es posible sobrescribir el atributo de shape
de un ndarray
:
a = np.arange(12)
a.shape = (3, 4)
print(a)
# [[ 0 1 2 3]
# [ 4 5 6 7]
# [ 8 9 10 11]]
Este comportamiento puede ser sorprendente al principio, pero los ndarray
s se almacenan en bloques contiguos de memoria, y su shape
solo especifica cómo este flujo de datos debe interpretarse como un objeto multidimensional.
Hasta un eje en la tupla de shape
puede tener un valor de -1
. numpy
entonces numpy
la longitud de este eje para ti:
a = np.arange(12)
print(a.reshape((3, -1)))
# [[ 0 1 2 3]
# [ 4 5 6 7]
# [ 8 9 10 11]]
O:
a = np.arange(12)
print(a.reshape((3, 2, -1)))
# [[[ 0 1]
# [ 2 3]]
# [[ 4 5]
# [ 6 7]]
# [[ 8 9]
# [10 11]]]
Múltiples dimensiones no especificadas, por ejemplo, a.reshape((3, -1, -1))
no están permitidas y lanzarán un ValueError
.
Operaciones de matriz de difusión
Las operaciones aritméticas se realizan elementwise en matrices de Numpy. Para matrices de forma idéntica, esto significa que la operación se ejecuta entre elementos en los índices correspondientes.
# Create two arrays of the same size
a = np.arange(6).reshape(2, 3)
b = np.ones(6).reshape(2, 3)
a
# array([0, 1, 2],
# [3, 4, 5])
b
# array([1, 1, 1],
# [1, 1, 1])
# a + b: a and b are added elementwise
a + b
# array([1, 2, 3],
# [4, 5, 6])
Las operaciones aritméticas también pueden ejecutarse en matrices de diferentes formas por medio de la difusión Numpy. En general, una matriz se "difunde" sobre la otra para que las operaciones elementales se realicen en subarreglas de forma congruente.
# Create arrays of shapes (1, 5) and (13, 1) respectively
a = np.arange(5).reshape(1, 5)
a
# array([[0, 1, 2, 3, 4]])
b = np.arange(4).reshape(4, 1)
b
# array([0],
# [1],
# [2],
# [3])
# When multiplying a * b, slices with the same dimensions are multiplied
# elementwise. In the case of a * b, the one and only row of a is multiplied
# with each scalar down the one and only column of b.
a*b
# array([[ 0, 0, 0, 0, 0],
# [ 0, 1, 2, 3, 4],
# [ 0, 2, 4, 6, 8],
# [ 0, 3, 6, 9, 12]])
Para ilustrar esto aún más, considere la multiplicación de matrices 2D y 3D con subdimensiones congruentes.
# Create arrays of shapes (2, 2, 3) and (2, 3) respectively
a = np.arange(12).reshape(2, 2, 3)
a
# array([[[ 0 1 2]
# [ 3 4 5]]
#
# [[ 6 7 8]
# [ 9 10 11]]])
b = np.arange(6).reshape(2, 3)
# array([[0, 1, 2],
# [3, 4, 5]])
# Executing a*b broadcasts b to each (2, 3) slice of a,
# multiplying elementwise.
a*b
# array([[[ 0, 1, 4],
# [ 9, 16, 25]],
#
# [[ 0, 7, 16],
# [27, 40, 55]]])
# Executing b*a gives the same result, i.e. the smaller
# array is broadcast over the other.
¿Cuándo se aplica la difusión de matriz?
La difusión tiene lugar cuando dos matrices tienen formas compatibles .
Las formas se comparan por componentes partiendo de las que se arrastran. Dos dimensiones son compatibles si son iguales o una de ellas es 1
. Si una forma tiene una dimensión mayor que la otra, no se comparan los componentes excedentes.
Algunos ejemplos de formas compatibles:
(7, 5, 3) # compatible because dimensions are the same
(7, 5, 3)
(7, 5, 3) # compatible because second dimension is 1
(7, 1, 3)
(7, 5, 3, 5) # compatible because exceeding dimensions are not compared
(3, 5)
(3, 4, 5) # incompatible
(5, 5)
(3, 4, 5) # compatible
(1, 5)
Aquí está la documentación oficial sobre la difusión de matriz .
Rellena una matriz con el contenido de un archivo CSV
filePath = "file.csv"
data = np.genfromtxt(filePath)
Se admiten muchas opciones, consulte la documentación oficial para obtener una lista completa:
data = np.genfromtxt(filePath, dtype='float', delimiter=';', skip_header=1, usecols=(0,1,3) )
Numpy matriz n-dimensional: la ndarray
La estructura de datos principal en numpy es la ndarray
(abreviatura de la matriz n -dimensional). ndarray
s son
- homogéneos (es decir, contienen elementos del mismo tipo de datos)
- contienen elementos de tamaños fijos (dados por una forma , una tupla de n enteros positivos que especifican los tamaños de cada dimensión)
Matriz unidimensional:
x = np.arange(15)
# array([ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14])
x.shape
# (15,)
Matriz bidimensional:
x = np.asarray([[0, 1, 2, 3, 4], [5, 6, 7, 8, 9], [10, 11, 12, 13, 14]])
x
# array([[ 0, 1, 2, 3, 4],
# [ 5, 6, 7, 8, 9],
# [10, 11, 12, 13, 14]])
x.shape
# (3, 5)
Tridimensional:
np.arange(12).reshape([2,3,2])
Para inicializar una matriz sin especificar su contenido usa:
x = np.empty([2, 2])
# array([[ 0., 0.],
# [ 0., 0.]])
Adivinación de tipo de datos y casting automático.
El tipo de datos está configurado para flotar por defecto
x = np.empty([2, 2])
# array([[ 0., 0.],
# [ 0., 0.]])
x.dtype
# dtype('float64')
Si se proporcionan algunos datos, numpy adivina el tipo de datos:
x = np.asarray([[1, 2], [3, 4]])
x.dtype
# dtype('int32')
Tenga en cuenta que al realizar asignaciones numpy intentará convertir automáticamente los valores para que se ajusten al tipo de datos del ndarray
x[1, 1] = 1.5 # assign a float value
x[1, 1]
# 1
# value has been casted to int
x[1, 1] = 'z' # value cannot be casted, resulting in a ValueError
Difusión de matriz
Consulte también Operaciones de matriz de difusión .
x = np.asarray([[1, 2], [3, 4]])
# array([[1, 2],
[3, 4]])
y = np.asarray([[5, 6]])
# array([[5, 6]])
En terminología matricial, tendríamos una matriz 2x2 y un vector fila 1x2. Todavía somos capaces de hacer una suma.
# x + y
array([[ 6, 8],
[ 8, 10]])
Esto se debe a que la matriz y
está " estirada " para:
array([[5, 6],
[5, 6]])
para adaptarse a la forma de x
.
Recursos:
- Introducción a la ndarray a partir de la documentación oficial: La matriz N-dimensional (ndarray)
- Referencia de la clase: ndarray .