PyLab [Parte 2]: Datos básicos NumPy

NumPy:

Como ya dijimos en el anterior tutorial PyLab [Parte 1] PyLab es como se denomina a todo un paquete de librerías con las que hacer cálculos científicos. De todas las librerías si tuviera que destacar alguna sería sin duda NumPy. La destacaría porque casi todas las demás librerías dependen de NumPy. Esto es así porque en NumPy se definen el tipo de datos por excelencia en la investigación, los vectores n dimensionales. Los problemas en investigación pueden tener muchas dimensiones, variables de estado que formen un sistemas de ecuaciones algebrodiferenciales. Para resolver estos problemas conviene hacer una matriz de dimensión n, y de ahí la importancia de NumPy.

Si queréis miraros todas las cosas que podéis hacer con Numpy y SciPy os dejo la documentación oficial y en la que baso mis tutoriales:

NumPy + SciPy - Referencia

Si has sido de los valientes que te has interesado por la documentación te habrás percatado de que cada una de las guías de documentación tienen más páginas que los "Pilares de la Tierra" de Ken Follett. Por eso la importancia de centrarnos sólo en lo más interesante y que cada uno se centre en lo que le resulta más útil. Insisto, aquí sólo vamos a ver unas pinceladas de las herramientas más comunes.

Estoy seguro que muchos de vosotros no entenderéis porque es importante NumPy por hacer vectores o arrays si con el propio lenguaje de Python ya puedes hacer vectores y puedes hacer operaciones elemento a elemento. Por ejemplo con lo que ya conocíamos de Python podríamos hacer:

c = [] for i in range(len(a)): c.append(a[i]*b[i])

Con eso creamos un vector C en el que cada elemento es el resultado de multiplicar los correspondientes elementos de los vectores A y B. El problema viene cuando los vectores A y B tienen muchos elementos, no 10 ó 100 sino miles de elementos que signifiquen muestras de resultados de experimentos. Si hiciéramos la misma operación en C/C++ los cálculos serían mucho más veloces. El código en C/C++ para hacer lo mismo que en el ejemplo anterior sería éste.

for (i = 0; i < rows; i++): { c[i] = a[i]*b[i]; }

Cuando usamos NumPy lo que estamos haciendo es a través de Python ejecutar código en C que hace las operaciones y nos devuelve los resultados a Python, así tenemos lo mejor de dos mundos. Además los desarrolladores de NumPy nos lo han puesto muy fácil sobrecargando muchos operadores. Éste es el código en Python usando la librería NumPy, insisto en que es igual de rápido que el ejemplo de C++.

c = a*b

Creo que ya os he convencido. Vamos a ver como declarar vectores y que operaciones básicas podemos usar utilizando NumPy.

Declaración de n-arrays:

Cuando manejamos muchos datos conviene especificar de que tipo son, ya que esto nos determina la precisión de las muestras. Los tipos de datos que podemos manejar con NumPy son:

Así un programa en el que creamos varias variables podría ser:>>> import numpy as np >>> x = np.int_(20) >>> x 20 >>> y = np.uint([1,2,3,4]) #primera manera de crear un array >>> y array([1, 2, 3, 4], dtype=uint32) >>> z = np.array([6.4, 4.3, -2.2], dtype=np.float32) #segunda manera de crear un array >>> z array([ 6.4000001 ,  4.30000019, -2.20000005], dtype=float32) >>> #Creamos un array de tuplas de números complejos >>> x = np.array([[ 1.+0.j, 2.+0.j], [ 0.+0.j, 0.+0.j], [ 1.+1.j, 3.+0.j]]) >>> x array([[ 1.+0.j,  2.+0.j], [ 0.+0.j,  0.+0.j], [ 1.+1.j,  3.+0.j]])

Ciertos tipos de vectores son muy típicos y tenemos herramientas para automatizar su creación. Algunos de estos vectores son:

>>> x1 = np.zeros((5,2)) #vector todo ceros >>> x1 array([[ 0.,  0.], [ 0.,  0.], [ 0.,  0.], [ 0.,  0.], [ 0.,  0.]]) >>> y1 = np.ones((5,3)) #vector todo unos >>> y1 array([[ 1.,  1.,  1.], [ 1.,  1.,  1.], [ 1.,  1.,  1.], [ 1.,  1.,  1.], [ 1.,  1.,  1.]]) >>> z1 = np.arange(20,30) #Un vector con los números de inicio y fin >>> z1 array([20, 21, 22, 23, 24, 25, 26, 27, 28, 29]) >>> #Inicio, fin y cantidad equidistantes de numeros en ese intervalo >>> w1 = np.linspace(30,40,num=20,endpoint=True) >>> w1 array([ 30.        ,  30.52631579,  31.05263158,  31.57894737, 32.10526316,  32.63157895,  33.15789474,  33.68421053, 34.21052632,  34.73684211,  35.26315789,  35.78947368, 36.31578947,  36.84210526,  37.36842105,  37.89473684, 38.42105263,  38.94736842,  39.47368421,  40.        ])

Operaciones de Indexación:

Hay muchas maneras de indexar la información de un vector. Un ejemplo bastante curioso, por la sencillez que resulta crear un índice condicional, puede ser el siguiente:

>>> x2 = np.arange(3,15,dtype=np.uint16) #Creamos un vector de prueba >>> print x2 [ 3  4  5  6  7  8  9 10 11 12 13 14] >>> mayoresQueOcho = x2>8 #creamos el índice >>> print mayoresQueOcho [False False False False False False  True  True  True  True  True  True] >>> print x2[mayoresQueOcho] [ 9 10 11 12 13 14]

Sólo pongo un ejemplo para que se vea el concepto, para ver más maneras de indexar consultar la documentación. Seguramente irán apareciendo más formas de indexar según salgan ejemplos en los que lo necesitemos.

Atributos estándar:

Cuando creamos un array, en realidad no es un vector propiamente dicho, sino es un objeto tipo 'np.array' y ese objeto además de tener la cadena de valores de n dimensiones tiene otros atributos que nos pueden ser útiles. Por ejemplo nos pueden servir para saber las dimensiones del vector, para conseguir el vector traspuesto (cambiar por columnas), etc. Los atributos estándar que podemos usar son:

Un ejemplo de como utilizar estos atributos: >>> y = np.array([[1,2,3],[4,4,4]]) >>> y array([[1, 2, 3], [4, 4, 4]]) >>> y.T  #muestro el atributo y traspuesto array([[1, 4], [2, 4], [3, 4]])

Métodos Estándar:

Siguiendo en la línea de ver los arrays como objetos, tenemos una serie de métodos que podemos utilizar con los np.array. La lista con los métodos que tenemos es la siguiente:

Y con esta tabla terminamos esta segunda parte de tutoriales dedicados a PyLab. Podéis ver todos los tutoriales de esta serie en el siguiente enlace: Tutoriales PyLab ¡¡Nos vemos en más tutoriales sobre Arduino o Python!!