Terminamos la serie de entradas de la librería Numpy. En la presente entrada, Numpy III, presento unos ejemplos finales para el uso de la librería. Además de la librería Numpy, utilizaré la librería matplotlib para la visualización de datos.

Para el lector interesado, puede acceder a las entradas previas en los siguientes enlaces:
Los ejemplos de utilización de la librería Numpy a presentar en esta entrada son los siguientes:
- Generación aleatoria de números.
- Transformación de arrays de una dimensión a otra.
- Álgebra linear.
- Operaciones sobre conjuntos.
- Serialización de arrays.
1.- Generación aleatoria de números.
Para la generación de números aleatorios emplearemos la función randn; para la definición de la semilla de generación, emplearemos la función seed; y, para definir un objeto de estado para la generación de números, emplearemos el objeto RandomState.
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:
seed = np.random.seed(123)
randn = np.random.randn(3)
print(f'randn=\n{randn}\n')
rang1 = np.random.RandomState(seed=123)
array_rang1 = rang1.randn(3)
print(f'array_rang1=\n{array_rang1}\n')
rang2 = np.random.RandomState(seed=123)
array_rang2 = rang2.randn(100, 2) # Retorna una distribución normal
print(f'array_rang2=\n{array_rang2}\n')
plt.scatter(array_rang2[:, 0], array_rang2[:, 1])
rang3 = np.random.RandomState(seed=123)
normal_distribution = 2. * rang3.randn(100, 2) + 5.
plt.scatter(normal_distribution[:, 0], normal_distribution[:, 1])
plt.show()
La salida por consola son los siguientes:
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]]
La gráfica generada en el ejemplo anterior es la que se muestra en el siguiente gráfico:

2.- Transformación de arrays de una dimensión a otra.
La creación de array n-dimensionales los podemos crear a partir de un array de una dimensión. Para realizar el cambio de dimensión, se realiza con la función reshape; con esta función, se puede especificar las dimensiones de forma explícita o implícito. Para realizar el proceso inverso, empleamos la función flatten; y, por último, para concatenar arrays, se emplea la función concatenate. En el siguiente snippet se muestra ejemplos de uso:
array = np.array([1, 2, 3, 4, 5, 6])
print(f'array=\n{array}\n')
array_23 = array.reshape(2, 3)
print(f'array_23=\n{array_23}\n')
print(f'may_share_memory=\n{np.may_share_memory(array_23, array)}\n')
array_2_1 = array.reshape(2, -1)
print(f'array_2_1=\n{array_2_1}\n')
array_1_2 = array.reshape(-1, 2)
print(f'array_1_2=\n{array_1_2}\n')
array2 = np.array([[1, 2, 3],
[4, 5, 6]])
print(f'array2=\n{array2}\n')
array2_1 = array2.reshape(-1)
print(f'array2_1=\n{array2_1}\n')
print(f'array2.ravel()=\n{array2.ravel()}\n') # ravel es flatten
print(f'np.may_share_memory(array2.flatten(), array2)={np.may_share_memory(array2.flatten(), array2)}') # False
print(f'np.may_share_memory(array2.ravel(), array2) ={np.may_share_memory(array2.ravel(), array2)}') # True
ary = np.array([1, 2, 3])
ary_concatenate = np.concatenate((ary, ary))
print(f'ary_concatenate=\n{ary_concatenate}\n')
La salida por consola es la siguiente:
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 = np.array([[1, 2, 3],
[4, 5, 6]])
column_vector = np.array([[1, 2, 3]]).reshape(-1, 1)
print(f'matrix=\n{matrix}\n')
print(f'column_vector=\n{column_vector}\n')
result = np.matmul(matrix, column_vector)
print(f'matrix X column_vector=\n{result}\n')
# Más eficiente con dot.
print(f'np.dot(row_vector, row_vector)=\n{np.dot(row_vector, row_vector)}\n')
print(f'np.dot(matrix, row_vector)=\n{np.dot(matrix, row_vector)}\n')
print(f'np.dot(matrix, column_vector)=\n{np.dot(matrix, column_vector)}\n')
print(f'matrix.transpose()=\n{matrix.transpose()}\n')
print(f'matrix.T=\n{matrix.T}\n')
print(f'np.dot(matrix, matrix.T)=\n{np.dot(matrix, matrix.T)}\n')
print(f'np.matmul(matrix, matrix.T)=\n{np.matmul(matrix, matrix.T)}\n')
La salida por consola es la siguiente:
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]]
4.- Operaciones sobre conjuntos.
Las operaciones de intersección, diferencia, unión o conjunto único sin repeticiones, se realizan respectivamente con las siguientes funciones: intersect1d, setdiff1d, union1d y unique. En el siguiente snippet de código se muestra ejemplos de uso:
array = np.array([1, 1, 2, 3, 1, 5])
array_set = np.unique(array)
print(f'array_set=\n{array_set}\n')
array1 = np.array([1, 2, 3])
array2 = np.array([3, 4, 5, 6])
print(f'array1=\n{array1}\n')
print(f'array2=\n{array2}\n')
array_intersec = np.intersect1d(array1, array2, assume_unique=True)
print(f'array_intersec=\n{array_intersec}\n')
array_diff = np.setdiff1d(array1, array2, assume_unique=True) # aaray1 - array2
print(f'array_diff=\n{array_diff}\n')
array_union = np.union1d(array1, array2)La librería Numpy es aquella librería pensada y preparada para realizar operaciones matemáticas orientadas a distintos ámbitos de la ciencia la cual, en mi caso, me permita profundizar en casos prácticos de Machine Learning.
print(f'array_union=\n{array_union}\n')
La salida por consola es la siguiente:
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]
5.- Serialización de arrays.
Para almacenar los valores de un array en un fichero, empleamos la función save; para almacenar un array con los índices, se emplea la función savez; y, para realizar la carga de un fichero en memoria, se emplea la función load. Los ficheros con los que se operan tienen extensión .npz.
En el siguiente snippet de código se muestra unos ejemplos de uso de estas funciones:
array = np.array([1, 2, 3])
np.save('ary-data.npy', array)
data_file = np.load('ary-data.npy')
print(f'data_file=\n{data_file}\n')
array2 = np.array([1, 2, 3, 4, 5, 6])
np.savez('ary2-data.npz', array, array2)
ary2_data = np.load('ary2-data.npz')
print(f'ary2_data=\n{ary2_data}\n')
array2_key = ary2_data.keys()
print(f'array2_key=\n{array2_key}\n')
print(f'ary2_data["arr_0"]=\n{ary2_data["arr_0"]}\n')
print(f'ary2_data["arr_1"]=\n{ary2_data["arr_1"]}\n')
kwarg = {'ary1': array, 'ary2': array2}
np.savez('ary3-data.npz', **kwarg)
ary3_data = np.load('ary3-data.npz')
print(f'ary3_data=\n{ary3_data}\n')
print(f'ary3_data["ary1"]=\n{ary3_data["ary1"]}\n')
print(f'ary3_data["ary2"]=\n{ary3_data["ary2"]}\n')
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]
La librería Numpy es aquella librería pensada y preparada para realizar operaciones matemáticas orientadas a distintos ámbitos de la ciencia la cual, en mi caso, me permita profundizar en casos prácticos de Machine Learning.