Numpy
Numpy
Numpy
Numpy es una librería Python open-source para computación científica que permite tener el
poder de computación de lenguajes como C o Fortran en lenguaje Python. En la presente
entrada, Numpy I, realizaré una breve presentación y realizaré unos ejemplos básicos.
Los ejemplos practicos que mostraré en los siguientes apartados están desarrollados con
Python 3.6. Las dependencias de las librerías utilizadas son las siguientes: numpy y
matplotlib; y, para la utilización de las funciones en cada módulo, es necesario importar la
librería de la siguiente forma:
1import numpy as np
Los ejemplos de utilización de la librería Numpy a presentar en esta entrada son los
siguientes:
Array integer:
[[1 2 3]
[4 5 6]]
Type=int64
Para crear un array de elementos de tipos reales a partir del array anterior, utilizamos la
función astype con el tipo float32 definidos en Numpy, el snippet ejemplo es el siguiente:
1array_float_32 = arrayld.astype(np.float32)
2print(f'Array float32:\n{array_float_32}')
3print(f'Type={array_float_32.dtype}\n')
Array float32:
[[1. 2. 3.]
[4. 5. 6.]]
Type=float32
Para crear un array de dos dimensiones de elementos enteros a partir de una lista, se utiliza
la función array y se especifica el tipos int64. Una vez creado el array, podemos conocer
sus características con las siguientes funciones:
array_2_dimesion=
[[1 2 3]
[4 5 6]]
array_2_dimesion.itemsize=8
array_2_dimesion.size=6
array_2_dimesion.ndim=2
array_2_dimesion.shape=(2, 3)
array_ahape=(3,)
1 def generator():
2 for i in range(10):
3 if not (i % 2):
4 yield i
gen = generator()
5 array_generator = np.fromiter(gen, dtype=int)
6 print(f'array_generator={array_generator}')
7 generator_expression = (i for i in range(10) if i % 2)
8 array_generator_expression = np.fromiter(generator_expression,
9 dtype=int)
print(f'array_generator_expression={array_generator_expression}')
10
array_generator=[0 2 4 6 8]
array_generator_expression=[1 3 5 7 9]
array_3_3_1=
[[1. 1. 1.]
[1. 1. 1.]
[1. 1. 1.]]
Otra forma de crear arrays con inicializaciones determinadas se pueden realizar con las
siguientes funciones:
1
2
# Inicializadores de arrays.
3 array_3_3_1 = np.ones((3, 3))
4 print(f'array_3_3_1=\n{array_3_3_1}\n')
5 array_3_3_0 = np.zeros((3, 3))
6 print(f'array_3_3_0=\n{array_3_3_0}\n')
7 array_eye_diagonal = np.eye(3)
print(f'array_eye_diagonal=\n{array_eye_diagonal}\n')
8 array_diagonal = np.diag((3, 3, 3))
9 print(f'array_diagonal=\n{array_diagonal}\n')
10array_arange_float = np.arange(4., 10.)
11print(f'array_arange_float=\n{array_arange_float}\n')
array_arange_int = np.arange(5)
12print(f'array_arange_int=\n{array_arange_int}\n')
13array_arange_interval = np.arange(1., 11., 2)
14print(f'array_arange_interval=\n{array_arange_interval}\n')
15array_insterval_space_1 = np.linspace(0., 1., num=5)
16print(f'array_insterval_space_1=\n{array_insterval_space_1}\n')
array_insterval_space_2 = np.linspace(0., 1., num=6)
17print(f'array_insterval_space_2=\n{array_insterval_space_2}\n')
18
19
array_3_3_0=
[[0. 0. 0.]
[0. 0. 0.]
[0. 0. 0.]]
array_eye_diagonal=
[[1. 0. 0.]
[0. 1. 0.]
[0. 0. 1.]]
array_diagonal=
[[3 0 0]
[0 3 0]
[0 0 3]]
array_arange_float=
[4. 5. 6. 7. 8. 9.]
array_arange_int=
[0 1 2 3 4]
array_arange_interval=
[1. 3. 5. 7. 9.]
array_insterval_space_1=
[0. 0.25 0.5 0.75 1. ]
array_insterval_space_2=
[0. 0.2 0.4 0.6 0.8 1. ]
1
2 array = np.array([1, 2, 3])
3 print(f'array=\n{array}\n')
4 print(f'array[0]=\n{array[0]}')
print(f'array[1]=\n{array[1]}\n')
5 print(f'array[:2]=\n{array[:2]}\n')
6 print(f'array[1:]=\n{array[1:]}\n')
7 array_22 = np.array([[1, 2, 3], [4, 5, 6]])
8 print(f'array=\n{array_22}\n')
print(f'array_22[0,0]=\n{array_22[0, 0]}')
9 print(f'array_22[-1,-1]=\n{array_22[-1, -1]}\n')
10print(f'array_22[0]=\n{array_22[0]}\n')
11print(f'array_22[:, 0]=\n{array_22[:, 0]}\n')
12print(f'array_22[:, :2]=\n{array_22[:, :2]}\n')
13
array=
[1 2 3]
array[0]=
1
array[1]=
2
array[:2]=
[1 2]
array[1:]=
[2 3]
array=
[[1 2 3]
[4 5 6]]
array_22[0,0]=
1
array_22[-1,-1]=
6
array_22[0]=
[1 2 3]
array_22[:, 0]=
[1 4]
array_22[:, :2]=
[[1 2]
[4 5]]
1
2 # Forma1: Suma 1 a los elementos de la lista
list = [[1, 2, 3], [4, 5, 6]]
3 list_mas_1 = [[cell + 1 for cell in row] for row in list] # Incrementamos
4 en 1
5 print(f'list_mas_1=\n{list_mas_1}\n')
6 # Forma2: Suma 1
array_nd_list_mas_1 = np.add(list, 1)
7 print(f'array_nd_list_mas_1=\n{array_nd_list_mas_1}\n')
8 # Forma3: Suma 1
9 ndarray_3 = np.array(list)
10array_nd_list_mas_12 = ndarray_3 + 1
11print(f'array_nd_list_mas_12=\n{array_nd_list_mas_12}\n')
ndarray_cuadrada = np.array(list)
12array_nd_list_cuadrado = ndarray_cuadrada**2
13print(f'array_nd_list_cuadrado=\n{array_nd_list_cuadrado}\n')
14
list_mas_1=
[[2, 3, 4], [5, 6, 7]]
array_nd_list_mas_1=
[[2 3 4]
[5 6 7]]
array_nd_list_mas_12=
[[2 3 4]
[5 6 7]]
array_nd_list_cuadrado=
[[ 1 4 9]
[16 25 36]]
1
2 ndarray = np.array(list)
3 print(f'np.add.reduce(ndarray)={np.add.reduce(ndarray)}')
print(f'np.sum(ndarray, axis=0)={np.sum(ndarray, axis=0)}')
4 print(f'np.sum(ndarray, axis=1)={np.sum(ndarray, axis=1)}')
5 print(f'ndarray.sum()={ndarray.sum()}')
6 print(f'ndarray.mean()={ndarray.mean()}')
7 print(f'ndarray.std()={ndarray.std()}')
8 print(f'ndarray.var()={ndarray.var()}')
print(f'ndarray.max()={ndarray.max()}')
9 print(f'ndarray.min()={ndarray.min()}')
10print(f'ndarray.argmax()={ndarray.argmax()}')
11print(f'ndarray.argmin()={ndarray.argmin()}')
12
np.add.reduce(ndarray)=[5 7 9]
np.sum(ndarray, axis=0)=[5 7 9]
np.sum(ndarray, axis=1)=[ 6 15]
ndarray.sum()=21
ndarray.mean()=3.5
ndarray.std()=1.707825127659933
ndarray.var()=2.9166666666666665
ndarray.max()=6
ndarray.min()=1
ndarray.argmax()=5
ndarray.argmin()=0
Numpy II
Los ejemplos de utilización de la librería Numpy a presentar en esta entrada son los
siguientes:
Sean dos arrays con la misma dimensión y número de elementos por dimensión, la
operación suma se realiza con el operador +. El snippet del código es el siguiente:
array1 + array2=[5 7 9]
Sea un array de dos dimenciones con tres elementos por dimensión y un array de una
dimensión e igual número de elementos que el primero. El snippet del código es el
siguiente:
Sea un array de dos dimensiones con tres elementos y un array de dos dimensiones de un
elemento por dimensión. El resultado es una array de dos dimensiones de tres elementos en
el que se ha incrementado el valor del segundo array. El snippet del código es el siguiente:
center_array=
[102 105]
array=
[[ 1 102 3]
[ 4 105 6]]
Si se desea realizar una copia de una dimensión se utiliza la función copy. En el siguiente
ejemplo, se realiza una copia de una dimensión de una array inicial. El snippet de ejemplo
es el siguiente:
second_row=
[104 105 106]
array2=
[[1 2 3]
[4 5 6]]
Para determinar si una referencia es una copia o forma parte de una estructura se emplea la
función may_share_memory. A continuación, se muestran dos ejemplos de ejemplos
previos. El snippet de código es el siguiente:
first_row = array2[:1]
1np.may_share_memory(first_row, array2)
2print(f'np.may_share_memory(first_row,
3array2)=\n{np.may_share_memory(first_row, array2)}')
4print(f'np.may_share_memory(second_row,
array2)=\n{np.may_share_memory(second_row, array2)}')
np.may_share_memory(first_row, array2)=
True
np.may_share_memory(second_row, array2)=
False
Para obtener arrays que sean subconjuntos de un array, podemos realizar seleccion de
posiciones de una determinada dimensión. En el siguiente ejemplo, se imprimen todos los
elementos de la primera dimensión y el primer y último elemento de la segundo; y, por
último, el caso contrario, último y primero. El snippet del código es el siguiente:
array3=
[[1 2 3]
[4 5 6]]
array3[:, [0,2]]=
[[1 3]
[4 6]]
array3[:, [2,0]]=
[[3 1]
[6 4]]
Por último, se pueden realizar operaciones de comparación de los elementos y obtener array
lógicos con el resultado. En el siguiente ejemplo, se imprimen los elementos mayores a 3;
impresión de los elementos que son mayores a 3; y, por último, se compone un predicado
lógico. El snippet del código es el siiguiente:
array3 > 3=
[[False False False]
[ True True True]]
array3[array3 > 3]=
[4 5 6]
array3[(array3 > 2) & (array3 <5)]=
[3 4]
array_mayor_2=
[False False True True]
Con los resultados lógicos podemos realizar operaciones para poder operar con ellos. Para
ello, podemos emplear las siguientes funciones:
1print(f'array[array_mayor_2]=\n{array[array_mayor_2]}\n')
2print(f'array_mayor_2.sum()=\n{array_mayor_2.sum()}\n')
3print(f'array_mayor_2.nonzero()=\n{array_mayor_2.nonzero()}\n')
4print(f'(array > 2).nonzero()=\n{(array > 2).nonzero()}\n')
array[array_mayor_2]=
[3 4]
array_mayor_2.sum()=
2
array_mayor_2.nonzero()=
(array([2, 3]),)
Para poder realizar un tratamiento más específico, podemos utilizar la función where en la
cuál podemos declarar qué valor asignar al resultado si cumple una condición, o bien,
cuando no la cumple. En el siguiente snippet se muestra un ejemplo de uso de la función
where:
Otra forma de trabajar con predicados sin la función where es declarando un predicado con
una condición. Una vez creado el predicado, lo aplicamos en el array como una indexación
asignando el valor para el caso de éxito, o bien, utilizando el carácter ~ para el caso de no
cumplirse. En el siguiente snippet se muestra un ejemplo de uso de ejemplo:
array2=[0 0 1 1]
Numpy III
Los ejemplos de utilización de la librería Numpy a presentar en esta entrada son los
siguientes:
Para definir una distribución, empleados la función scatter del módulo matplotlib.pyplot; y,
para representar desde un punto de vista gráfico, se emplea la función show. El snippet de
código de ejemplo es el siguiente:
1 seed = np.random.seed(123)
randn = np.random.randn(3)
2 print(f'randn=\n{randn}\n')
3
4 rang1 = np.random.RandomState(seed=123)
5 array_rang1 = rang1.randn(3)
6 print(f'array_rang1=\n{array_rang1}\n')
7 rang2 = np.random.RandomState(seed=123)
8 array_rang2 = rang2.randn(100, 2) # Retorna una distribución normal
9 print(f'array_rang2=\n{array_rang2}\n')
10
11plt.scatter(array_rang2[:, 0], array_rang2[:, 1])
12
13rang3 = np.random.RandomState(seed=123)
normal_distribution = 2. * rang3.randn(100, 2) + 5.
14plt.scatter(normal_distribution[:, 0], normal_distribution[:, 1])
15plt.show()
16
17
18
randn=
[-1.0856306 0.99734545 0.2829785 ]
array_rang1=
[-1.0856306 0.99734545 0.2829785 ]
array_rang2=
[[-1.08563060e+00 9.97345447e-01]
...
[-3.41261716e-01 -2.17946262e-01]]
array=
[1 2 3 4 5 6]
array_23=
[[1 2 3]
[4 5 6]]
may_share_memory=
True
array_2_1=
[[1 2 3]
[4 5 6]]
array_1_2=
[[1 2]
[3 4]
[5 6]]
array2=
[[1 2 3]
[4 5 6]]
array2_1=
[1 2 3 4 5 6]
array2.ravel()=
[1 2 3 4 5 6]
np.may_share_memory(array2.flatten(), array2)=False
np.may_share_memory(array2.ravel(), array2) =True
ary_concatenate=
[1 2 3 1 2 3]
3.- Algebra linear.
La multiplicación de matrices así como la operación con la matriz transpuesta es una
operación típica, en el presente apartado, presentamos dos funciones para realizar el
producto de dos matrices: función matmul, multiplica dos matrices pasadas por parámetro;
y, la función dot, realiza la misma funcionalidad pero más eficiente. Para calcular la
función transpuesta, empleamos la función T de un array. En el siguiente ejemplo, se
muestra un snippet de código con ejemplos de productos de matrices.
matrix=
[[1 2 3]
[4 5 6]]
column_vector=
[[1]
[2]
[3]]
matrix X column_vector=
[[14]
[32]]
np.dot(row_vector, row_vector)=
14
np.dot(matrix, row_vector)=
[14 32]
np.dot(matrix, column_vector)=
[[14]
[32]]
matrix.transpose()=
[[1 4]
[2 5]
[3 6]]
matrix.T=
[[1 4]
[2 5]
[3 6]]
np.dot(matrix, matrix.T)=
[[14 32]
[32 77]]
np.matmul(matrix, matrix.T)=
[[14 32]
[32 77]]
array_set=
[1 2 3 5]
array1=
[1 2 3]
array2=
[3 4 5 6]
array_intersec=
[3]
array_diff=
[1 2]
array_union=
[1 2 3 4 5 6]
1
2 array = np.array([1, 2, 3])
3 np.save('ary-data.npy', array)
4
5 data_file = np.load('ary-data.npy')
6 print(f'data_file=\n{data_file}\n')
7
8 array2 = np.array([1, 2, 3, 4, 5, 6])
np.savez('ary2-data.npz', array, array2)
9
10ary2_data = np.load('ary2-data.npz')
11print(f'ary2_data=\n{ary2_data}\n')
12
13array2_key = ary2_data.keys()
14print(f'array2_key=\n{array2_key}\n')
15print(f'ary2_data["arr_0"]=\n{ary2_data["arr_0"]}\n')
print(f'ary2_data["arr_1"]=\n{ary2_data["arr_1"]}\n')
16
17kwarg = {'ary1': array, 'ary2': array2}
18np.savez('ary3-data.npz', **kwarg)
19
20ary3_data = np.load('ary3-data.npz')
21print(f'ary3_data=\n{ary3_data}\n')
print(f'ary3_data["ary1"]=\n{ary3_data["ary1"]}\n')
22print(f'ary3_data["ary2"]=\n{ary3_data["ary2"]}\n')
23
24
La salida por consola es la siguiente:
data_file=
[1 2 3]
ary2_data=
<numpy.lib.npyio.NpzFile object at 0x7f580fa5a128>
array2_key=
KeysView(<numpy.lib.npyio.NpzFile object at 0x7f580fa5a128>)
ary2_data["arr_0"]=
[1 2 3]
ary2_data["arr_1"]=
[1 2 3 4 5 6]
ary3_data=
<numpy.lib.npyio.NpzFile object at 0x7f57e8b7def0>
ary3_data["ary1"]=
[1 2 3]
ary3_data["ary2"]=
[1 2 3 4 5 6]