Accediendo a los datos de las matrices con Numpy. Copia de Matrices. Añadir elementos a un array con numpy.append()
La forma en la que se accede a los datos de las matrices en Numpy es similar a como se hace con las listas en Python. La diferencia está en que mientras que las listas son unidimensionales las matrices son ciertamente multidimensionales. Esto significa que mientras que en una lista solo hay un índice para cada elemento, con Numpy al tratarse de matrices puede haber varios valores índices (uno para cada dimensión)
Vamos a explicar esto mejor, con un ejemplo.
Para acceder a un elemento concreto de una matriz de 3 dimensiones, tenemos que usar el valor del índice de cada dimensión separada por comas:
>>> import numpy as np
# Importamos la librería Numpy
>>> a = np.array([[1,2,3],[4,5,6],[7,8,9]])
>>> print(a)
[[1 2 3]
[4 5 6]
[7 8 9]]
>>> print(a[0,2])
3
>>> print(a[1,1])
5
# Seleccionamos el elemento contando desde la izquierda.
>>> print(a[2,-3])
7
>>> print(a[3,-1][2,-1])
8
# realmente se pondría print(a[2][1]) pero he preferido poner la resta
# ya que los elementos se empiezan a contar en el cero, con lo que el
# elemento 8, estaría en la fila 2 y columna 1 en python.
>>> m = np.arange(10)
>>> m
array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
>>> m[1:3]
array([1, 2])
>>> m[3:]
array([3, 4, 5, 6, 7, 8, 9])
>>> m[:-1]
array([0, 1, 2, 3, 4, 5, 6, 7, 8])
>>> m[4:] = 0
array([0, 1, 2, 3, 0, 0, 0, 0, 0, 0])
m[1:7:2]
array([1, 3, 0])
>>> n = np.zeros((5,5))
>>> n
array([[0., 0., 0., 0., 0.],
[0., 0., 0., 0., 0.],
[0., 0., 0., 0., 0.],
[0., 0., 0., 0., 0.],
[0., 0., 0., 0., 0.]])
>>> n[1:3,1:3]=3
>>> n
array([[0., 0., 0., 0., 0.],
[0., 3., 3., 0., 0.],
[0., 3., 3., 0., 0.],
[0., 0., 0., 0., 0.],
[0., 0., 0., 0., 0.]])
Matrices y copia de matrices.
>>> matriz_a = np.array([1,3,5,7,9])
>>> matriz_b = matriz_a
>>> matriz_b[2:]=-7
>>> matriz_a
array([ 1, 3, -7, -7, -7])
>>> matriz_a = np.array([1,3,5,7,9])
>>> matriz_b = matriz_a.copy()
# Esto copia la matriz_a en matriz_b y hace a esta independiente.
Hay que tener en cuenta que si hacemos slicing a una matriz, cualquier modificación que hagamos quedará reflejada en la matriz. Por tanto si queremos hacer una copia de una parte de una matriz debemos utilizar el método copy()
>>> original = np.arange(10)
>>> una_parte = original[1:4] # Esto es una vista, si cambiamos algún elemento
de una_parte los cambios se reflejaran en los elementos [1:4] de la original.
>>> una_parte = original[1:4].copy() # Esto es una verdadera copia de una parte
de la matriz original.
Añadir elementos a un array con np.append()
Veamos unos cuantos ejemplos de todo esto.
Añadir un número al final de un array unidimensional.
>>> import numpy as np
>>> arr = np.array([1, 2, 3, 4, 5])
# Queremos añadir el número 10 al final de este array
>>> np.append(arr, 10)
array([ 1, 2, 3, 4, 5, 10])
#O también podríamos agregar otro arrray.
>>> np.append(arr, [11, 12])
array([ 1, 2, 3, 4, 5, 11, 12])
# Como puedes ver en este último caso el array original no se modifica,
# ya que como ves no aparece el número 10 del caso anterior.
Agregar elementos a matrices o arrays que no sean unidimensionales.
Cuando agregamos elementos a una matriz es necesario que indiquemos mediante la propiedad axis si los nuevos elementos se agregan por filas o por columnas. En el caso de que no lo hagamos, la matriz se aplanará antes de añadir los elementos, obteniéndose un array unidimensional.
Por ejemplo:
>>> mat = np.array([[1, 2, 3],[4, 5, 6]])
>>> np.append(mat, [11, 12])
array([ 1, 2, 3, 4, 5, 6, 11, 12])
Como veremos más adelante, para poder añadir una nueva fila a la matriz esta tiene que ser compatible, es decir tiene que tener el mismo número de columnas que la original. Sino es así Numpy te dará un error. Si en el ejemplo anterior intentamos añadir estos dos elementos a la matriz original, nos dará un error ya que nuestra matriz tiene 3 columnas y le estamos tratando de añadir solo 2 elementos en vez de 3.
>>> np.append(mat, [[11, 12]], axis=0)
ValueError: all the input array dimensions for the concatenation axis
must match exactly, but along dimension 1, the array at index 0 has
size 3 and the array at index 1 has size 2
Por tanto si queremos añadirle una nueva fila a nuestra matriz esta tiene que tener 3 elementos para poder hacerlo, además de establecer el parámetro axis=0. Vamos a añadir entonces [11, 12, 13] a nuestra matriz.
>>> np.append(mat, [[11, 12, 13]], axis=0)
array([[ 1, 2, 3],
[ 4, 5, 6],
[11, 12, 13]])
Si lo que queremos añadir es una nueva columna el método funciona exactamente igual. Los elementos a agregar deberán estar en una matriz con el mismo número de filas que la matriz original.
Como nuestra matriz original tiene 2 filas si queremos añadir una nueva columna deberemos añadir una matriz con 2 elementos y que tenga la misma dimensión.
>>> np.append(mat, [[11], [12]], axis=1)
array([[ 1, 2, 3, 11],
[ 4, 5, 6, 12]])
Y con esto hemos visto lo básico del método np.append() de Numpy, sigamos repasando lo visto en el capítulo con un nuevo ejercicio.
EJERCICIO
Creemos una matriz con una dimensión de 4*4 con valores aleatorios.
Luego extraigamos todos los valores de la segunda fila.
A continuación extraeremos todos los valores de la tercera columna.
Asignaremos el valor 0.31 al subarreglo 2x2 superior izquierdo.
Para finalizar crearemos una matriz de 8x8 con un patrón de tablero de damas, es decir, alternando ceros y unos :
1 0 1
0 1 0
1 0 1
...
SOLUCIÓN.
>>> import numpy as np
"Creamos una matriz de 4x4 con valores arbitrarios enteros del 0,1"
>>> a=np.random.rand(4,4) # o números enteros con np.random.randint(0,11,(4,4))
>>> print(a)
[[0.86244938 0.10086289 0.49685669 0.89849421]
[0.63274446 0.90953088 0.87053284 0.32822434]
[0.94201367 0.60204052 0.72596334 0.36410397]
[0.68208797 0.46102898 0.59214942 0.89901397]]
"Extraer cada elemento de la segunda fila."
>>> print(a[1])
[0.63274446 0.90953088 0.87053284 0.32822434]
"Extraer cada elemento de la tercera columna"
print(a[:,2])
[0.49685669 0.87053284 0.72596334 0.59214942]
"Asignar un valor de .31 a la matriz de 2*2 de arriba a la izquierda"
a[:2,:2]=0.31
print(a)
[[0.31 0.31 0.49685669 0.89849421]
[0.31 0.31 0.87053284 0.32822434]
[0.94201367 0.60204052 0.72596334 0.36410397]
[0.68208797 0.46102898 0.59214942 0.89901397]]
"Crear una matriz de 8x8 alternando 0 y 1"
#b = np.array([[(i+j+1) % 2 for i in range(8)] for j in range(8)]) solución alternativa
b=np.zeros((8,8),dtype="int")
b[::2,::2]=1
b[1::2,1::2]=1
print(b)
[[1 0 1 0 1 0 1 0]
[0 1 0 1 0 1 0 1]
[1 0 1 0 1 0 1 0]
[0 1 0 1 0 1 0 1]
[1 0 1 0 1 0 1 0]
[0 1 0 1 0 1 0 1]
[1 0 1 0 1 0 1 0]
[0 1 0 1 0 1 0 1]]
No hay comentarios:
Publicar un comentario