NumPy#


Definición#

NumPy (Python numérico) es una biblioteca de Python de código abierto que se utiliza en casi todos los campos de la ciencia y la ingeniería. Es el estándar universal para trabajar con datos numéricos en Python y es el núcleo de los ecosistemas científicos de Python y PyData. Los usuarios de NumPy incluyen a todos, desde codificadores principiantes hasta investigadores experimentados que realizan investigación y desarrollo científico e industrial de vanguardia.

Importando NumPy#

Para acceder a la librería NumPy y a sus funciones se debe hacer lo siguiente:

import numpy as np #np viene a ser el alias que nos ayudará a indentificar la librería con mayor facilidad

Diferencias entre las listas y los NumPy array#

a = [1, 2, 3]
b = np.array(a)
print(a)
print(b)
[1, 2, 3]
[1 2 3]

Mientras que las listas pueden contener elementos de diversos tipos (números, cadenas, listas, etc) en una misma lista, los array de NumPy solo pueden contener elementos de un tipo, es decir son homogéneos.

Los elementos array de Numpy son más rápidos y compactos que las listas de Python, además consumen menos memoria.

¿Qué son los NumPy array?#

Es la estructura principal de la librería NumPy. Esta estructura se podría entender como una colección de datos del mismo tipo y del mismo tamaño. Esta se puede generar a partir de una lista, una tupla, etc. con np.array. tal como se muestra a continuación.

a = np.array ((1,2,3,4,5))
b = np.array ([1,2,3,4,5])
print(a)
# print(b)
[1 2 3 4 5]

En caso de que queramos trabajar con una matriz podemos hacer los siguiente.

a = np.array([[1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12]])
print(a)
[[ 1  2  3  4]
 [ 5  6  7  8]
 [ 9 10 11 12]]

La manera de acceder a los elementos de nuestro array es muy similar a la manera como se accede a los elementos de una lista.

a = np.array([[1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12]])

print('La primera fila de mi matriz es : {0}'.format(a[0]))
print('La segunda fila de mi matriz es : {0}'.format(a[1]))
print('La tercera fila de mi matriz es : {0}'.format(a[2]))
La primera fila de mi matriz es : [1 2 3 4]
La segunda fila de mi matriz es : [5 6 7 8]
La tercera fila de mi matriz es : [ 9 10 11 12]

En caso de querer acceder a alguna columna, podríamos hacerlo de la siguiente manera.

a = np.array([[1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12]])
# print(a[2,3])
# print(a[:,1:2])
print('La primera columna de mi matriz es : {0}'.format(a[:,0:1]))
print('La segunda columna de mi matriz es : {0}'.format(a[:,1:2]))
print('La tercera columna de mi matriz es : {0}'.format(a[:,2:3]))
print('La cuarta columna de mi matriz es : {0}'.format(a[:,3:4]))
La primera columna de mi matriz es : [[1]
 [5]
 [9]]
La segunda columna de mi matriz es : [[ 2]
 [ 6]
 [10]]
La tercera columna de mi matriz es : [[ 3]
 [ 7]
 [11]]
La cuarta columna de mi matriz es : [[ 4]
 [ 8]
 [12]]

La librería de NumPy nos permite crear array con elementos iguales a 0 y 1 con np.zeros() y np.ones() respectivamente; tal como se muestra a continuación.

a = np.zeros(5)
b = np.ones (5)
print(a)
print(b)
[0. 0. 0. 0. 0.]
[1. 1. 1. 1. 1.]

Adicionalmente se podría crear un array en el que sus elementos sean números al azar, la ventaja de usar este frente a los dos casos anteriormente mostrados es la velocidad ya que su creación depende del espacio en la memoria que se cuenta en el momento. Además podemos especificar el tipo de datos con el que trabajaremos.

a = np.empty(50)
print(a)
[ 9.39138810e-312  9.39126283e-312  8.71804670e+250  1.19470713e+243
  1.16497569e-310  3.63507105e-027  2.00429134e-313  1.03539814e-308
  1.33360293e+241  1.21929878e-310  1.00562508e-248  2.85308965e-313
  2.14793507e-308  1.33360297e+241  1.05632950e-310  1.16443429e-171
  6.46048250e-313  4.37300893e-308  1.33360300e+241  1.81685280e-310
  9.22559891e-143  5.61168418e-313  5.40840706e-308  1.33360307e+241
  2.46872990e-310  8.83636824e-090  9.85567576e-313  2.88067937e+214
 -1.06149314e-248  7.43412929e-251  5.68824653e-299  4.78064292e-299
  4.78064292e-299  4.78064292e-299  4.78064748e-299  5.07928728e-299
  4.78064292e-299  4.78064292e-299  1.37832411e-279  8.31719769e-251
  2.17977806e-269  3.22393283e-269  9.04901890e-211  3.98111223e-269
  3.98114400e-269  2.84229010e-269  4.31556869e-308  2.11592073e-289
  8.50339234e+014  4.05133830e-320]

De manera similar a como se hacía con range, NumPy también cuenta con un método que permite crear un array con un rango de elementos.np.arange()

a = np.arange(10)
b = np.arange(1, 11)
c = np.arange(0, 11, 2)

print(a)
print(b)
print(c)
[0 1 2 3 4 5 6 7 8 9]
[ 1  2  3  4  5  6  7  8  9 10]
[ 0  2  4  6  8 10]

También se podría usar np.linspace() para crerar un array con valores que están espacias en un intervalo establecido.

El primer y segundo parámetro indicar el primer y último elemento del array respectivamente mientras que el tercer parámetro indica la cantidad de elementos que tendrá el array.

a = np.linspace(0,10, num = 6)
print(a)
[ 0.  2.  4.  6.  8. 10.]

Agregando, removiendo y ordenando los elementos.#

Para ordenar los elementos simplemente usamos la método np.sort()

arr = np.array([2, 1, 5, 3, 7, 4, 6, 8])
arr_order = np.sort(arr)
print(arr_order)
[1 2 3 4 5 6 7 8]
a = np.array([1, 2, 3, 4])
b = np.array([5, 6, 7, 8])
a_b = np.concatenate((a, b))
print(a_b)
[1 2 3 4 5 6 7 8]
x = np.array([[1, 2], [3, 4]])
y = np.array([[5, 6]])

# a = np.concatenate((x,y))
b = np.concatenate((x, y), axis = 0 )
print(b)
[[1 2]
 [3 4]
 [5 6]]

Cambiando la forma de nuestro array#

Mediante el método shape podremos averiguar la forma de nuestro array.

Con np.reshape podremos cambiar la forma de nuestra array.

a = np.arange(6)
print(a)
print(a.shape)

b = np.array ([[1,2,3], [4,5,6], [7,8,9], [10,11,12]])
b = np.arange(1,13).reshape(4,3)
print(b)
print(b.shape)

a = np.arange(6)
print(a)
b = np.reshape(a, (2,3))

print(b)
print(b.shape)
[0 1 2 3 4 5]
(6,)
[[ 1  2  3]
 [ 4  5  6]
 [ 7  8  9]
 [10 11 12]]
(4, 3)
[0 1 2 3 4 5]
[[0 1 2]
 [3 4 5]]
(2, 3)

Leyendo información desde un archivo#

Para leer información de un archivo txt podemos usar np.loadtxt.

data_import = np.loadtxt('Archivo_prueba.txt')
print(data_import)
print(type(data_import))
[ 1.  2.  3.  4.  5.  6.  7.  8.  9. 10. 11. 12. 13. 14. 15. 16. 17. 18.
 19. 20.]
<class 'numpy.ndarray'>

A partir de información existente podemos generar un nuevo array.

a = data_import[:10].reshape(2,5)
# print(a)
b = data_import[10:].reshape(2,5)
a, b
(array([[ 1.,  2.,  3.,  4.,  5.],
        [ 6.,  7.,  8.,  9., 10.]]),
 array([[11., 12., 13., 14., 15.],
        [16., 17., 18., 19., 20.]]))

A partir de estas matrices generadas podemos crear nueva matrices poniendo una la derecha de la otra o por debajo de la otra.

mv = np.vstack((a, b))
mh = np.hstack((a, b))

print(mh)
print(mh.shape)
[[ 1.  2.  3.  4.  5. 11. 12. 13. 14. 15.]
 [ 6.  7.  8.  9. 10. 16. 17. 18. 19. 20.]]
(2, 10)

Operaciones básicas elementos array#

a = np.arange(10, dtype= float)
b = np.ones(10)

print(a)
print(b)
# print(a+b)
# print(a-b)
# print(a*b)
print(a*a)
print(a/b)
[0. 1. 2. 3. 4. 5. 6. 7. 8. 9.]
[1. 1. 1. 1. 1. 1. 1. 1. 1. 1.]
[ 0.  1.  4.  9. 16. 25. 36. 49. 64. 81.]
[0. 1. 2. 3. 4. 5. 6. 7. 8. 9.]

En caso de que se quiera sumar todos los elementos de un array se puede usar el sum()

a = np.arange(10).sum()
print(a)
print(np.arange(10))
45
[0 1 2 3 4 5 6 7 8 9]
data_import = np.loadtxt('Archivo_prueba.txt')
a = data_import[:10].reshape(2,5)


print(a)
# print(a.sum(axis=0))
print(a.min(axis=1))
print(a.max())
[[ 1.  2.  3.  4.  5.]
 [ 6.  7.  8.  9. 10.]]
[1. 6.]
10.0

Obtener elementos únicos y contarlos#

En caso de tener elementos que se repiten podemos usar np.unique.

a = np.array([11, 11, 12, 13, 14, 15, 16, 17, 12, 13, 11, 14, 18, 19, 20])
print(a)
unique_values = np.unique(a)
print(unique_values)
[11 11 12 13 14 15 16 17 12 13 11 14 18 19 20]
[11 12 13 14 15 16 17 18 19 20]

En caso de que queramos obtener más información podemos hacerlo de la siguiente manera.

unique_values, indices_list = np.unique(a, return_index=True)
print(len(a))
print(unique_values)
# print(indices_list)
unique_values, occurrence_count = np.unique(a, return_counts=True)
print(occurrence_count)
15
[11 12 13 14 15 16 17 18 19 20]
[3 2 2 2 1 1 1 1 1 1]

Como guardar y cargar objetos Numpy#

a = np.empty(50)
print(a)
np.save('Archivo_gen.npy', a)
np.savetxt('Archivo_gen.txt', a)
[ 9.39138810e-312  9.39126283e-312  8.71804670e+250  1.19470713e+243
  1.16497569e-310  3.63507105e-027  2.00429134e-313  1.03539814e-308
  1.33360293e+241  1.21929878e-310  1.00562508e-248  2.85308965e-313
  2.14793507e-308  1.33360297e+241  1.05632950e-310  1.16443429e-171
  6.46048250e-313  4.37300893e-308  1.33360300e+241  1.81685280e-310
  9.22559891e-143  5.61168418e-313  5.40840706e-308  1.33360307e+241
  2.46872990e-310  8.83636824e-090  9.85567576e-313  2.88067937e+214
 -1.06149314e-248  7.43412929e-251  5.68824653e-299  4.78064292e-299
  4.78064292e-299  4.78064292e-299  4.78064748e-299  5.07928728e-299
  4.78064292e-299  4.78064292e-299  1.37832411e-279  8.31719769e-251
  2.17977806e-269  3.22393283e-269  9.04901890e-211  3.98111223e-269
  3.98114400e-269  2.84229010e-269  4.31556869e-308  2.11592073e-289
  8.50339234e+014  4.05133830e-320]
b = np.load('Archivo_gen.npy')
print(b)
b = np.loadtxt('Archivo_gen.txt')
print(b)
[ 9.39138810e-312  9.39126283e-312  8.71804670e+250  1.19470713e+243
  1.16497569e-310  3.63507105e-027  2.00429134e-313  1.03539814e-308
  1.33360293e+241  1.21929878e-310  1.00562508e-248  2.85308965e-313
  2.14793507e-308  1.33360297e+241  1.05632950e-310  1.16443429e-171
  6.46048250e-313  4.37300893e-308  1.33360300e+241  1.81685280e-310
  9.22559891e-143  5.61168418e-313  5.40840706e-308  1.33360307e+241
  2.46872990e-310  8.83636824e-090  9.85567576e-313  2.88067937e+214
 -1.06149314e-248  7.43412929e-251  5.68824653e-299  4.78064292e-299
  4.78064292e-299  4.78064292e-299  4.78064748e-299  5.07928728e-299
  4.78064292e-299  4.78064292e-299  1.37832411e-279  8.31719769e-251
  2.17977806e-269  3.22393283e-269  9.04901890e-211  3.98111223e-269
  3.98114400e-269  2.84229010e-269  4.31556869e-308  2.11592073e-289
  8.50339234e+014  4.05133830e-320]
[ 9.39138810e-312  9.39126283e-312  8.71804670e+250  1.19470713e+243
  1.16497569e-310  3.63507105e-027  2.00429134e-313  1.03539814e-308
  1.33360293e+241  1.21929878e-310  1.00562508e-248  2.85308965e-313
  2.14793507e-308  1.33360297e+241  1.05632950e-310  1.16443429e-171
  6.46048250e-313  4.37300893e-308  1.33360300e+241  1.81685280e-310
  9.22559891e-143  5.61168418e-313  5.40840706e-308  1.33360307e+241
  2.46872990e-310  8.83636824e-090  9.85567576e-313  2.88067937e+214
 -1.06149314e-248  7.43412929e-251  5.68824653e-299  4.78064292e-299
  4.78064292e-299  4.78064292e-299  4.78064748e-299  5.07928728e-299
  4.78064292e-299  4.78064292e-299  1.37832411e-279  8.31719769e-251
  2.17977806e-269  3.22393283e-269  9.04901890e-211  3.98111223e-269
  3.98114400e-269  2.84229010e-269  4.31556869e-308  2.11592073e-289
  8.50339234e+014  4.05133830e-320]

Ejercicios de aplicación#

Encuentre los valores que coinciden en dos elementos array#

Z1 = np.random.randint(0,20,10)
print(Z1)
Z2 = np.random.randint(0,10,10)
print(Z2)
print(np.intersect1d(Z1,Z2))
[ 6 16  6  9 18 17 17 18  9  8]
[4 2 5 7 0 2 5 0 6 5]
[6]

Cambiar algun valor que cumpla una condición establecida por otro valor#

a = np.arange(20)
print(a)
b = np.where( a % 2 != 0, a, 0)

print(b)
[ 0  1  2  3  4  5  6  7  8  9 10 11 12 13 14 15 16 17 18 19]
[ 0  1  0  3  0  5  0  7  0  9  0 11  0 13  0 15  0 17  0 19]