
0. Capítulos anteriores

1. Introducción
Numpy es actualmente la mejor manera de trabajar con Arrays, Vectores y Matrices, en Python. Es una de las librerías más eficientes en CPU para hacer operaciones con matrices y convertir Python en algo más parecido a Matlab y acelerar Python al máximo.
Tiene un montón de funciones que me encantaría cubrir su totalidad, pero lamentablemente no me daría el tiempo a seguir la serie. Y es una opción fundamental para el Data Science en Python.
Pero, ¿Por qué numpy es tan rápido y eficiente?, lo que pasa es que numpy usa un proceso que se llama “vectorización” en donde toma la lógica de tu código y la pre compila a C detrás de los telones. Eso nos otorga el poder de C pero en Python.
Para instalar Numpy, abre una terminal en cualquier parte de tu sistema, y si tienes Python instalado escribe “pip install numpy” y con esto estarás listo para usar Numpy y aprovechar todo el poder que nos ofrece.
Ahora lo siguiente que haremos es crear una Array de Numpy

Pero sabes, ese nombre me parece muy largo, en Python por defecto tenemos una función de las importaciones y es que le podemos poner un alias, para luego llamar a esa librería, por su alias entendiendo alias como sobrenombre, es decir puedo llamar a las librerías de Python con el nombre que yo quiera y usarlas bajo ese nombre, así que, por convención entre todos los que usan numpy, es abreviar el nombre de numpy a np, así en vez de escribir numpy.*, solo escribiremos np.*, para hacer esto debo importar de mi libreria de la siguiente manera.

Algo importante que debemos comprender, es que los datos en la medida de lo posible deben ser homogéneos, es decir, cuando yo estoy definiendo mi array no puedo hacer esto.

No es que Numpy no me deje hacer esto, pero se considera una mala práctica, porque numpy asigna los tipos de datos a todo nuestro array, porque pretende que todos los datos serán del mismo tipo, si tengo valores flotantes, todos deben ser valores flotantes, o si tengo caracteres todos mis valores deben ser caracteres, porque o si no nos pasara a asignar el tipo de dato objeto que puede causar problemas para optimizar nuestro algoritmo, es que tenemos una array muy grande, como sabes, cada valor es un pequeño archivo en la memoria ram, y ocupa espacio, y si manejamos bien nuestros tipo de datos, ocupan mucho menos espacio.
A parte nuestra arrays de Numpy tienen una particularidad, que se comportan como matrices, es decir, todas las propiedades matemáticas que tienen las matrices también las tiene nuestra numpy array. Y el estas arrays tienen un tipo de dato específico, y es el siguiente.

Y puedo definir una Array de dos dimensiones, o una Array de dos dimensiones de la siguiente manera.

y este tipo ndarray, tiene unos valores que tienes que saberte:
shape: Este valor nos indica la forma que tiene nuestra array, en filas y columnas en caso una array de dos dimensiones, con este diagrama lo entenderás mejor.

2. ndim: Este valor también está relacionado con la forma de nuestra Array ,y si la forma de nuestra Array tiene 2 valores es una array de 2 dimensiones, y si tiene 3 valores es una array de 3 dimensiones, y eso es lo que nos indicará este valor, cuántos valores hay presentes la forma de mi Array.
3. size: Este valor nos indica el número total de los elementos dentro de mi array, se obtiene multiplicando la forma de mi Array.
4. itemsize: Este valor nos indica el tamaño en la memoria RAM de cada uno de mis elementos en bytes.
5. dtype: Este valor nos indica el tipo de datos de los elementos dentro de mi Array, como habíamos dicho tenemos que intentar de que sean Homogéneos.
Así se ven todos los valores de mi Array:

Si quiero calcular el tamaño de mi Array en la memoria ram, puedo hacerlo con estos valores, de la siguiente manera:

Ahora vamos a la siguiente sección.
Snippets:
https://gist.github.com/harpiechoise/9a0c2989a22dc1d03b14b593e57c0996

2. Creación de Arrays
Ahora veremos unos errores comunes dentro de la creación de Arrays, por ejemplo, el parámetro que recibe mi función np.array, es una lista, no importa cuantas listas contenga, mientras mis valores sean homogéneos todo está bien. Si digo esto no es porque si, ahora veremos un error común al usar numpy.

como habíamos dicho numpy asigna el tipo de dato a la Array completa, y por eso tenemos que tener datos homogéneos, pero numpy como habíamos dicho también reconoce el tipo de dato automáticamente, y lo asigna, veamos con más detenimiento esto

Como vemos numpy detecta solo el tipo de dato, y como vemos tanto mi “int64” como mi “float64” ocupan 4 bits de memoria. ¿Pero por que no puedo mezclar mis valores?, por lo siguiente

Prácticamente exponenciales nuestro peso en memoria. También puedo asignar mis tipos de datos manualmente, solo debes informarte en los rangos en los que calzan tus valores así puedes ahorrar memoria, creeme que más de una vez esto me salvó la vida, me he quedado muchas veces con la Memoria RAM llena. Para hacerlo tenemos dos formas de hacerlo, una es en la definición del Array y otra es luego de la definición, vamos a verlas

Si quieres saber los tipos de datos disponibles en numpy te los dejo aqui:
Tabla de Tipos de Datos en Numpy
Como habíamos dicho, podíamos cambiar el tipo de dato de mi Array luego de definirla, vamos a redefinir el tipo de dato de esta Array.

También tenemos un tipo de dato que está diseñado para los números complejos, y es el tipo Complex, vamos a verlo.

También tenemos una serie de utilidades para crear Arrays, por ejemplo si quiero crear una Array de ceros, tenemos una función predefinida para ello que recibe como parámetro la forma de la Array resultante.

También tengo una funcion para crear una Array de unos, y se ocupa de exactamente igual que a la anterior, y puedo definir un tipo de dato para esa Array.
Tambien tengo otra función, que toma estados aleatorios de la memoria para crear una Array de a las dimensiones que les indiquemos.

También tengo una funcion para hacer una Array de ceros o unos a partir de otra Array.
También podemos definir una función personalizada para crear Arrays como nosotros queramos.

La función no tiene que ser anónima, también tengo que tener tantos parámetros como dimensiones, y numpy le pasara un rango de valores a mi funcion que serán los argumentos de la función que le pase para crear mi Array y de esta forma puedo crear una Array a partir de una función personalizada.
También podemos crear rangos, es decir una especie de lista que valla entre los valores que yo le indique, eso lo haremos de la siguiente manera

Tenemos que tener en cuenta, que la función arange ignora el último número por lo que necesitamos sumar 1 al valor que queremos llegar.
También podemos especificar la distancia entre mis valores.

Recordemos que la manera de representar estos valores es en una recta numérica, y la diferencia entre dos valores siempre me dará su distancia, es decir que si yo resto 4 y 5, el resultado será esa distancia que hay entre los dos valores que en este caso es 1, y lo mismo pasa en este caso, si yo resto 12 y 14 la distancia entre estos valores será 2, eso significa el tercer parámetro
Pero esta función no recibe como parámetro números decimales, porque no tendría sentido pasarle dos números decimales sin especificar la distancia, es ambiguo, como sabre como espaciar mis valores, para eso tengo la función linspace

Aqui le estoy diciendo que quiero que divida las distancias entremedias de modo que 5 valores quedarán a la misma distancia en la recta numérica los unos de los otros.
Las últimas dos cosas que quiero decir, es que si yo muestro por consola una array con abreviada, en notación matemática

Esto se maneja con un valor que trae programado Numpy que dice que cuando mi array supere los 1000 elementos la mostrará de esta forma, pero yo puedo disminuir o aumentar este valor, por ejemplo, lo dejaré en 50

También tenemos una función para crear matrices de identidad de forma fácil, solo un valor ya que las matrices de identidad son cuadradas, pero no te preocupes hablaremos de ello luego en la parte de álgebra lineal. Para usar esta función debo hacer lo siguiente.

También tengo una funcion para hacer una matriz diagonal de 1 pero tengo mas opciones por este lado, por ejemplo si quiero mover mi diagonal tengo el parámetro K, vamos a ver un ejemplo.

También tenemos una de las utilidades que yo en lo personal mas amo de esta librería que es vectorize. Básicamente con esta utilidad puedo tomar cualquier función de python y aplicarla para crear cualquier Array de numpy. Pero un ejemplo habla más de lo que puedo hacerlo yo

Algo interesante es que podemos obtener las docstring de mi función, y esto se hace para saber como se usa la función, por lo general son mostradas con la función help(), para acceder a mi docstring hago lo siguiente

Lo último de lo que quiero hablar es de como guardar y cargar mis Arrays al disco para poder transferirlas o ocuparlas luego, para guardar mi array debo ocupar la función save de numpy

Estos nos creara un archivo con extensión npy, en este caso Array.npy ya que el nombre lo toma de la cadena que le paso y para cargarla debo usar la función load

Y por último, al igual que mis listas si reasigno mi variable a otra quedarán unidas, porque compartirán espacio de memoria, por ejemplo

En numpy tengo una funcion para saber si las dos listas están compartiendo el mismo espacio de memoria.

Y para solucionarlo debo copiar mi array en otra variable de la siguiente manera.

Snippets
https://gist.github.com/harpiechoise/6fb0ad51cdcb30bf13cbb32420f3ac80

3. Operaciones
Vamos a repasar unas de las mejores partes de Numpy, la parte que lo hace brillar con luz propia, y es su manera de realizar operaciones.
Y es que se pueden hacer operaciones aritméticas de python sobre las Arrays de Numpy y eso nos da un nivel muy grande de manejo sobre Numpy, por ejemplo si quiero sumar 10 a todos los valores de mi Array hago lo siguiente

En este caso iremos elemento por elemento, se puede aplicar cualquier operación aritmética de Python a nuestras Arrays, por ejemplo si quiero sumar o restar dos Arrays.

Para aplicar estas operaciones ambas arrays deben ser de las mismas dimensiones.
También tenemos una operacion aritmetica especial para el producto punto, esto lo discutiremos luego en la sección de Matemáticas, para sacar el producto punto se puede hacer de dos maneras

También puedo usar el operador de asignación de Python para hacer una “inplace operation”, por ejemplo si quiero multiplicar mi Array por 5.

También los arrays tienen algunas operaciones que comunes que se pueden sacar de forma fácil.

También tenemos operaciones universales, que son las siguiente:

Estas operaciones deben manejarlas, son un requisito para pasar a la seccion de Matematicas ya que ahi las veremos no tan a profundidad.
También podemos aplicar operaciones lógicas a nuestra array, ademas de operaciones de Bits, si no sabes las operaciones de Bits, en el principio de articulo esta el capitulo anterior. Para aplicar operaciones lógicas debemos hacer lo siguiente.

Las operaciones de Bits, no pueden ser aplicadas a valores de tipo Float.
También podemos hacer estas operaciones con números imaginarios.

También podemos aplicar estas operaciones a las columnas, para aplicar estas operaciones por ejemplo si quiero la suma de cada columna, debo hacer lo siguiente.

Para comprender los Ejes, o Axis, ve este diagrama

el axis = 1 son las columnas, y el axis = 0 son las filas.
Ahora vamos a lo siguiente que es la indexación
Snippets:
https://gist.github.com/harpiechoise/8929b52f2beb08a62a3a663af42e293a

4. Indexación en Numpy
Aquí veremos cómo trabajamos con los índices en las Arrays de numpy. La forma de trabajar con índices en una array es igual a la de Python solo que con variaciones, primero veamos cual es la forma en que trabajamos con indices en Python y que comparte con numpy

También podemos ir con un paso.

Y también podemos invertir el orden de las Arrays

Pero como numpy es para trabajar con Arrays multidimensionales tenemos algunas variaciones, podemos seleccionar Arrays dentro de Arrays, como lo hacíamos con las listas

Pero para hacerlo más estético, con numpy podemos hacerlo de la siguiente manera

Así nuestro código se va a ver mas limpio y ordenado, para comprender esta forma, debemos saber que el primer índice corresponde a las filas, y el segundo a las columnas, por lo que también puedo seleccionar valores de las filas o columnas de la siguiente manera

O también puedo traer una columna completa.

Entonces comprendiendo esto puedo seleccionar cada fila de igual manera, o cada columna, así puedo trabajar con Arrays multidimensionales, cada “,” representa a una dimensión del Array

Y si quiero seleccionar la última fila.

También puedo recorrer cada valor de mi matriz de cualquier dimensión aplanando la misma, es decir, convirtiendo todos sus valores a 1 dimensión.

Otra forma de convertir mi Array a 1 dimensión es con la función ravel.

También puedo usar operadores lógicos con el fin de filtrar valores de mis Arrays, por ejemplo si quiero saber todos los valores de mi Array que son mayores a 55.

Y como los valores booleanos son valores basados en Bits, puedo aplicar mis operaciones de Bits igualmente.

Estas funcionan de igual manera que mis operaciones lógicas en este caso.
También podemos manejar nuestras dimensiones, esto es lo que más usamos en Machine Learning para preparar los datos para un algoritmo.

Por ejemplo aquí tengo una matriz de dos dimensiones 3 filas y 4 columnas. La multiplicación de estos valores es la cantidad de valores que tengo dentro de mi Array en este caso 3 x 4 = 12.

Para saber qué forma tiene actualmente mi Array, tengo el atributo shape, esto me retornara las dimensiones de mi Array como dijimos en el pincipio.

Siguiendo la lógica de que la cantidad de valores de mi array es la multiplicación de estos dos valores, para cambiar la forma de ella también tiene que ser 12, por lo que puedo cambiarla a 12*2 que igual es 12, para cambiar la forma de mi matriz hago lo siguiente

Tambien tengo una funcion para permutar la forma de mi matriz, es decir intercambiar la posición de los valores del atributo Shape, que es T, esta explicación es lo que cuando saco la Traspuesta de una matriz, permuto sus dimensiones. Para saber la traspuesta de mi matriz hago lo siguiente

En caso de que quiera cambiar la forma de mi Array, y no se cual es una de las dimensiones, Numpy puede adivinar una se esas dimensiones automáticamente, pero para ello tiene faltar solo 1 valor, para hacer eso debemos.

Vamos con algunas funciones fundamentales que se me quedaron en el tintero de esta sección:
Volviendo a los índices, también podemos seleccionar varios índices a la vez.

También podemos reemplazar valores de mi array de la siguiente manera.

También podemos asignar varios indices de mi array

Si quiero saber el indice de mi valor máximo, puedo usar la funcion argmax:
Snippets
https://gist.github.com/harpiechoise/ce4ed9ebb0d69b6bd80e6c5786e3d436

5. Mi tintero
Aquí repasare las funciones muy usadas, pero que no halle una categoría donde ponerlas. Vamos a repasar algunas muy curiosas y otras muy usadas
Si quiero crear un Rango de fechas, por ejemplo desde el 1 de enero al 1 de febrero. Puedo hacer lo siguiente.

El formato que deben seguir nuestras fechas es “AAAA-MM-DD” siendo A: Año , M: Mes y D: Dia, y el formato Datetime64 también tiene un formato, en este caso lo configure a días, para saber todas las unidades con las que se pueden configurar visita este link:
Datetime Units.
Otra cosa muy útil que debemos saber es cómo apilar dos arrays, por ejemplo si quiero apilar mis arrays una encima de la otra.

En este caso segunda dimensión debe ser exactamente igual a la primera, es decir tener la misma cantidad de columnas.
Y si quiero apilarlas en el eje horizontal.

Y por ultimo, para generar una Array de números aleatorios como habrás notado es Numpy.random, pero si quiero agregarle un rango, es decir quiero generar una Array de aleatorios de números entre el 2 y el 52, debo hacer lo siguiente.


6. Agradecimientos
Si llegaste hasta aqui gracias, espero que hayas aprendido nuevas funciones de Numpy y agradezco que leas mis artículos al final, sin mas que decir hasta la próxima
Siguiente Capitulo
[embed]https://medium.com/@jcrispis56/machine-learning-parte-1-python-para-machine-learning-ce48d38302ba[/embed]
Comentarios
Publicar un comentario