Manual Python para desmemoriados.pdf

PYTHON PARA DESMEMORIADOS INGENIEROS DE GNURADIO ​1.​ Instalaciones y comandos de terminal ​2.​ Lios entre python 2 y py

Views 118 Downloads 0 File size 322KB

Report DMCA / Copyright

DOWNLOAD FILE

Recommend stories

Citation preview

PYTHON PARA DESMEMORIADOS INGENIEROS DE GNURADIO ​1.​ Instalaciones y comandos de terminal ​2.​ Lios entre python 2 y python 3 (Anaconda) y jupyter ​2.1.​ Consideraciones generales:

​2.2.​ Los Entornos virtuales de Python

​2.3.​ Instalación de componentes de python ​2.4.​ Actualizaciones

​2.5.​ Qué es Anaconda con respecto a cosas como Jupyter, python, etc ​2.6.​ Para que Jupyter reconozca python2 y python3: ​3.​ Tutoriales recomendados ​4.​ Programación por objetos en Python ​5.​ Comando Import. Aspectos relevante de los módulos. ​6.​ números complejos

​6.1.​ definir un número complejo ​6.2.​ La librería math y cmath

​7.​ Exponencial compleja ​8.​ Uso de librería de gnuradio

​8.1.​ Ejemplo 1 de uso de gnuradio por consola

​9.​ números aleatorios

​9.1.​ obtener la amplitud una señal de ruido blanco con gnuradio

​10.​ Gráficas

​10.1.​ Trucos de matplotlib.pyplot en 2D

​10.2.​ Trucos matplotlib para gráficas en 3D ​11.​ Vectores en python ​12.​ Trucos de numpy vectors

​12.1.​ llenar un vector con un número una cantidad de veces ​12.2.​ Llenar un vector de ceros

​12.3.​ Llenar un vector con N números aleatorios que oscilan entre 0 y 1 ​12.4.​ Llenar un vector con N números binarios aleatorios

​12.5.​ Llenar un vector con N números enteros aleatorios entre 0 y M

​12.7.​ Llenar un vector con N números flotantes aleatorios en un rango entre Mmin y Mmax ​12.8.​ Llenar un vector de ceros complejos

​12.9.​ Rebanar un vector, quitándole valores celdas (el diezmado)

​12.10.​ Llenar un vector x con N valores igualmente espaciados entre un mínimo y un máximo ​12.11.​ Llenar un vector con valores incrementados, 0,1,2,3,.... ​12.12.​ Llenar un array con valores de una función

​12.13.​ Cambiar periódicamente un paquete de celdas de un vector por ceros (diezmado al estilo Oppenhein) ​12.14.​ Insertar valores para que ocupen parte de un vector ​12.15.​ Unir o concatenar dos vectores

​12.16.​ crear un vector repitiendo otro N veces 12.17.​ Acortar tamaño de un vector

​12.18.​ Extraer parte de los datos de un vector ​13.​ Trucos de matrices

​13.1.​ matrix versus array

​13.2.​ Principales comandos

​13.3.​ Convertir un array 2D en uno 1D ​14.​ Programación científica

​14.1.​ La Matriz de covarianza en matemáticas ​14.2.​ la matriz de covarianza en python

​15.​ Instalación de librerías adicionales ​16.​ Graficar con Matplotlib

​16.1.​ Gráfica de tiempo real tipo osciloscopio

​1.​ Instalaciones y comandos de terminal Instalación del pip PIP es un sistema de gesti´on de paquetes utilizado para instalar y administrar software escritos en Python.Este puede ser instalado de manera sencilla con el siguiente comando: sudo apt-get install python-pip pip list Es para tener un listado de librerias instaladas en python pip -V Revisar la version de pip

​2.​ Lios entre python 2 y python 3 (Anaconda) y jupyter Un consejo de estilo es indicarle al editor, en el archivo donde está el programa, la versión de python usada, por ejemplo #!/usr/bin/env python2 # -*- coding: utf-8 -*################################################## # GNU Radio Python Flow Graph # Title: If Else # Generated: Thu Sep 13 11:39:57 2018 ################################################## [AQUÍ VA EL CUERPO DEL PROGRAMA]

​2.1.​ Consideraciones generales: ● ● ● ●

si quiere programar en python 2 a la fija, llame python2 si quiere programar en python 3 a la fija, llame python3 Al parecer gnuradio funciona sobre python2 python3 no soporta completamente a python2. Tampoco python2 puede leer todo lo de python3. Un truco de compatibilidad puede ser el siguiente: ○ usar solo comandos que estén en la intercepción entre las dos versiones. ○ Lo más profesional es usar los ​Entornos Virtuales de Python

​2.2.​ Los Entornos virtuales de Python Los entornos virtuales son la mejor solución para: ● no tener lios entre diferentes versiones de python. Puedes crear un entorno virtual (EV) para la versión de python que te interese, de manera que mientras estés en el EV lo que funcionará será esa versión ● Poder definir a cada proyecto justo lo que necesita, ni más ni menos. Puedes crear un entorno virtual para cada proyecto, de manera que cuando lo vayas a instalar en otro equipo, tengas claridad de justo las librerias que se requieren, ni más ni menos. ● Poder trabajar en un equipo que no es tuyo, que otras personas pueden usar para otros propósitos. Crea un entorno virtual para tí o para cada cosa tuya, allí siempre usarás tus recursos propios de python, no los de otras personas. ● Más detalles de cómo usar EV en: ​El Libro Internet de los Objetos

​2.3.​ Instalación de componentes de python ●

Hay componentes de python que tienen un mismo nombre, pero que deben ser instalados por separado para cada versión. Veamos dos ejemplos: ○ pip ■ Instalación en python2: sudo apt-get install python-pip ■ Instalación en python3: sudo apt-get install python3-pip ○ ipykernel ■ Instalación en python2: python2 -m pip install ipykernel ■ Instalación en python3: python3 -m pip install ipykernel ○ matplotlib. Al parece, esta si es comun para las dos versiones de python, pues en ambos casos vi que la version mas nueva es (2.1.1-2ubuntu3): ■ sudo apt-get install python3-matplotlib ■ Otra opción: sudo pip3 install matplotlib ■ sudo apt-get install python-matplotlib

​2.4.​ Actualizaciones ●

Antes que todo es importante actualizar ubuntu así: ○ Actualizar la lista de actualizacione: sudo apt-get update ○ Actualizar todo basado en la lista anterior: sudo apt-get upgrade



Hay paquetes que a veces requieren actualizaciones. Por ejemplo ○ Actualización de la libreria matplotlib: python2 -m pip install -U matplotlib A veces hay que desistalar y volver a instalr un paquete. Por ejemplo:



python -m pip uninstall matplotlib python -m pip install -U matplotlib

● ●

A veces hay que enviar los comandos precedidos de sudo A veces hay que logearse como root

​2.5.​ Qué es Anaconda con respecto a cosas como Jupyter, python, etc Lo que hay que entender es lo siguiente: ● Cuando uno instala Anaconda en un computador, ​como se explica en la página oficial​, lo que realmente se hace es una instalación desde cero de varios paquetes y software útil especialmente para los científicos de datos incluyendo: IDES (​Jupyter,

JupyterLab, Spyder y RStudio​), leguajes de programacion (python, la version que desees), herramientas y librerías científicas (​Dask, numpy, pandas y Numba​), librerias de visualizacion cientifica (​Bokeh , Datashader , Holoviews o Matplotlib​), ●



y nos quedamos cortos Lo primero que uno se pregunta es: todo eso se instala encima de lo que ya tiene el computador? es decir, se sobreescribe el python que el computador tiene instalado?. La respuesta es no. La segunda pregunta es: ¿entonces, cómo se logra que conviva lo que el computador tenía con lo nuevo instalado?. La respuesta está en lo siguiente, lo que se hace es crear un entorno virtual que es gestionado por Conda. Esto se hace de manera que, cuando tu reinicias tu computador, Conda es invocado y queda corriendo. Para entenderlo mejor, veamos qué mostraria un terminal de comandos antes de instalar Conda uis-e3t@uise3t-HP-ProDesk-600-G4-SFF:~$ Ahora veamos que tenemos luego de instalar Conda (base) uis-e3t@uise3t-HP-ProDesk-600-G4-SFF:~$

Vemos que apareció la palabra “(base)” antes que todo. Eso significa que estamos dentro del entorno virtual llamado “base” ● Cuando uno está en un Entorno Virtual como el que crea Anaconda, todas las aplicaciones de tu computadora funcionan como si este no existiera, excepto todo aquello relacionado con python y todas las herramientas que acompañan a Anaconda. Es decir, si invocas algo de lo instalado con Anaconda, se invocará lo que hay en ese ambiente virtual y no otras versiones. Por eso, si invocas python, se ignorará el python original de tu computadora y se usará el de Anaconda. ● En el caso de GRC de GNU Radio, este, aunque genera y corre codigo de python, ignorará el ambiente virtual de conda, pero si tu tomas un codigo de python generado por GRC y lo corres por tu cuenta, sin GRC, lo que estará usando será Anaconda y probablemente no funcionará porque lo más seguro es que GNU RAdio haya sido instalado fuera de Anaconda. Precisamente, los entornos virtuales están hechos para separar versiones de software. Uno se pregunta: tiene sentido instalar GNU RAdio dentro del entorno virtual que crea Anaconda? la respuesta es: si no



dependes de GRC sí es posible, recuerda que GRC ignorará lo creado por Anaconda. La tercera pregunta sería: entonces cómo puede uno usar el python original. El caso se da cuando se usa gnuradio con GRC, pues el GRC, al no pertenecer a Anaconda, ignora el entorno virtual. Pero si uno está en el entorno virtual y corre un código de python generado por GRC va a tener problemas, porque está usando el python de Anaconda y este no tiene instaladas las mismas librerías que está usando GRC. Al dia de hoy, no vemos la posibilidad de informarle a un aplicación como GRC o cualquier otra, que debe estar amarrada a un determinado entorno virtual, de manera que ignora su existencia. La solución es: puedes salir o entrar al entorno virtual con los siguientes comandos: conda deactivate: te permite salid del entorno virtual de anaconda conda activate: te permite entrar al entorno virtual de anaconda

​2.6.​ Para que Jupyter reconozca python2 y python3: ●



Prerrequisitos: ○ debe tener instalado pip tanto en python2 como en python3 ○ debe tener instalado ipykernel tanto en python2 como en python3 Hay que reubicar los kernels de python2 y python3 en una subcarpeta de jupyter con los siguientes comandos: python2 -m ipykernel install --user python3 -m ipykernel install --user

● ●

Si le aparece que no reconoce ipykernel, debe instalarlos, como se explica en siguiente capítulo cierre el editor de jupyter y el terminal y vuelva a abrir todo. Ahora aparecerán las dos opciones

​3.​ Tutoriales recomendados  ● ● ● ● ●

En español El wiki de la Fundacion Python Ayudas de Las librerias de pyhton Nuestro manual de manuales Programacion por Objetos en Python

​4.​ Programación por funciones

No vamos a detenernos en como programar y usar funciones pues hay buenos tutoriales para eso. Vamos a ver más bien casos especiales, donde comentemos las mayores fallas

El uso de global dentro de una función Es usual que comentamos el siguiente error: a = ​0 def​ foobar(): a = a + ​2 ​print​(a) foobar()

El código que he escrito arriba, genera el mismo error. El problema está en que en python​ cuando defines (o sea asignas valor) una variable local (a la función foobar en este caso) con un mismo nombre que una variable preexistente en un ámbito superior, ésta última variable deja de existir dentro de la función. Por tanto, dentro de foobar "a" no existe antes de que hagas: a ​ = a + ​2. ​y, claro, genera fallo. La solución es declarar dentro de la función que "a" existe fuera:

a = ​0 def​ foobar(): global a a = a + ​2 ​print​(a) foobar()

​5.​ Programación por objetos en Python

Para este caso, tratándose de ofrecer un recordatorio rápido, para alguien que ya sabía algo pero que lo olvidó, lo que recomienda es el siguiente tutorial: ●

Programación por Objetos en Python

​6.​ Comando Import. Aspectos relevante de los módulos. Lo que primero se aprende es a usar python como una calculadora con el intérprete, gracias a que Python como Matlab, es un lenguaje interpretado. Pero tan pronto como se requiera realizar operaciones más sofisticadas es necesario usar librerías. Un módulo puede ser una librería de clases con funciones y variables, pero en principio, puede ser cualquier archivo con código python pensado en que pueda ser usado por otros programas. El tema se explica en ​el modulo 6 del tutorial del software python fundation TIPS ● Aunque un módulo suele ser una biblioteca de clases, funciones, variables, en principio un módulo puede ser cualquier archivo con código python pensado en que pueda ser usado por otros programas. ● Al importar un módulo en python, el módulo no pasa a ser parte de nuestro código, como ocurre en c++ cuando se usa #include. Lo que ocurre realmente es lo siguiente: ○ Nuestro programa, el que hace la importación, lo que obtiene es una dirección o enlace sobre la ubicación del código, para facilitar su acceso. ● usted puede importar toda una librería, pero también sólo una parte de ella. Bueno, como en realidad la importación es solo una referencia, pues lo que se hace es con el fin de satisfacer el estilo del programador. Veamos estos dos casos ○ cuando se importa toda la librería, el uso de una función de ella se hace escribiendo el nombre de la librería seguida de un punto y la función import​ random print​(random.randrange(10))



cuando se importa solo una funcion de la librería, el uso de la función se realiza de manera directa

from​ random ​import​ randrange print​(randrange(10)) ○

Pero también se pueden importar varias funciones de una libreria

from random import randrange, choice print​(randrange(10)) print​(choice([​"uno"​, ​"dos"​, ​"tres"​])) ●

Ejemplo: ○ A continuación se muestra la imagen al crear un sencillo módulo. Es simplemente un código de python que guardamos con el nombre “mod1.py”



Ahora, mediante un terminal Ubuntu, nos ubicamos en la carpeta donde está el módulo, lo importamos y realizamos unos experimentos

# Esto se tomó de un terminal de Ubuntu # Nota: comenzamos por ubicarnos en la carpeta donde está el módulo, luego # llamamos el editor de python así: radiogis@RadioGIS-LP-1:~/Dropbox/EnUbuntuFull/Ej/Py/modulos$ python Python 2.7.10 (default, Oct 14 2015, 16:09:02) [GCC 5.2.1 20151010] on linux2 Type "help", "copyright", "credits" or "license" for more information. # Ya estamos en el editor de python >>> import mod1 >>> # Veremos que “x” no se puede usar directamente, sale error, pues no es parte de nuestro código >>> x Traceback (most recent call last): File "", line 1, in NameError: name 'x' is not defined >>> #Veremos que x se puede usar si se le antepone el nombre del módulo seguido de punto ... mod1.x 24 >>> # Nuestro código se puede apropiar de los valores de y atribuyendolos a r ... r=mod1.y >>> print r [2, 4, 5, 6.7] >>> r [2, 4, 5, 6.7] >>> z=mod1.d >>> print z manana >>> print mod1.d manana >>>



Pero, sí es posible incluir en nuestro código el contenido o parte del contenido de un módulo. Veamos

radiogis@RadioGIS-LP-1:~/Dropbox/EnUbuntuFull/Ej/Py/modulos$ python Python 2.7.10 (default, Oct 14 2015, 16:09:02) [GCC 5.2.1 20151010] on linux2

Type "help", "copyright", "credits" or "license" for more information. >>> from mod1 import y # Entonces vemos que “from” sirve para importar cosas del texto de un módulo, # mientras “import” sirve para importar un módulo. # “from” e “import” sirve para otras cosas, pero esto es ya cuando se habla de paquetes. # Se revisará más adelante. # Ahora veremos que y se puede invocar directamente, sin hacer mención a mod1. >>> y [2, 4, 5, 6.7] # Pero no se puede invocar con mod1. >>> mod1.y Traceback (most recent call last): File "", line 1, in NameError: name 'mod1' is not defined # Tampoco se pueden invocar los demás componentes de mod1.py >>> x Traceback (most recent call last): File "", line 1, in NameError: name 'x' is not defined >>> d Traceback (most recent call last): File "", line 1, in NameError: name 'd' is not defined >>> print y [2, 4, 5, 6.7] # Nota: sí es posible invocar directamente todo lo que hay en el modulo importado # si la importacion se hace así >>> from mod1 import * >>> x 24 >>> y [2, 4, 5, 6.7] >>> d 'manana' >>> # Nota: con lo anterior no se importa lo que comienza con _ ○ ○

reload(modulename). Puede ser usada en python cuando no se desea salir de la sesion actual, pero se ha modificado del módulo. Cuando python arranca desde un lugar diferente a donde está la carpeta

radiogis@radiogis01:~$ python

Python 2.7.10 (default, Oct 14 2015, 16:09:02) [GCC 5.2.1 20151010] on linux2 Type "help", "copyright", "credits" or "license" for more information. # python desconoce el lugar donde se encuentra el módulo >>> import mod1 Traceback (most recent call last): File "", line 1, in ImportError: No module named mod1 # Como Matlab, python tiene un path >>> sys.path Traceback (most recent call last): File "", line 1, in NameError: name 'sys' is not defined # Pero el path solo funciona si se importa el modulo sys >>> import sys # Allí podemos agregar la dirección de nuestro módulo >>> sys.path.append('/home/radiogis/Dropbox/EnUbuntuFull/Ej/Py/modulos') >>> sys.path ['', '/usr/lib/python2.7', '/usr/lib/python2.7/plat-x86_64-linux-gnu', '/usr/lib/python2.7/lib-tk', '/usr/lib/python2.7/lib-old', '/usr/lib/python2.7/lib-dynload', '/usr/local/lib/python2.7/dist-packages', '/usr/lib/python2.7/dist-packages', '/usr/lib/python2.7/dist-packages/PILcompat', '/usr/lib/python2.7/dist-packages/gtk-2.0', '/usr/lib/python2.7/dist-packages/ubuntu-sso-client', '/usr/lib/python2.7/dist-packages/wx-2.8-gtk2-unicode', '/home/radiogis/Dropbox/EnUbuntuFull/Ej/Py/modulos'] >>> import mod1 # con esto ya python puede ubicar el módulo >>> mod1.x 24 >>> Nota: cuando son módulos mas sofisticados, como los que se crean con GNU radio, se usa un proceso de instalación que lleva esos módulos a las bibliotecas de gnu radio, de modo que su ubicación será conocida por python ○

○ ○

Una ventaja de lo anterior las variables usadas en un módulo no entran en conflicto con variables del programa que invoca el módulo, aunque tengan el mismo nombre. Un módulo puede importar otros módulos Para importar modulos que están e un carpeta lejos de donde se está corriendo pyhton hay que dominar ​el concepto de “path” del modulo “sys”

​7.​ números complejos ​7.1.​ definir un número complejo No se requiere importar nada. Es tan simple como esto >>> x=3+2j >>> x (3+2j)

Las operaciones se suma, resta, multiplaciacion se pueden realizar de manera directa, sin importar ninguna librería. >>> x=3+2j >>> y=1+6j >>> z=x+y >>> z (4+8j) >>> s=x*y >>> s (-9+20j) >>> w=abs(x) >>> w 3.605551275463989

​7.2.​ La librería math y cmath La librería math no funciona solo funciona con variables de tipo float, pero no con variables complejas >>> import math >>> import cmath >>> f=cmath.atan(z) >>> f (1.5203354344612496+0.10008092715193644j) >>> f=math.atan(z) Traceback (most recent call last): File "", line 1, in TypeError: can't convert complex to float



​8.​ Exponencial compleja import numpy as np a=np.exp(3.j)

​9.​ Uso de librería de gnuradio Tenemos un​ manual para programar en serio con gnuradio​, pero es posible usar gnuradio para cosas muy sencillas, incluso en modo intérprete. Los trucos son: ● Al parecer, gnuradio no se puede importar sola para algo útil, sino una libreria dentro de ella. Por eso lo que se importa es una componente de gnuradio como: ○ digital: todas las funciones usadas en comunicaciones ○ analog: contiene todo tipo de fuentes ○ audio: fuentes de audio, bocina ○ eng_notatiton ○ filter: los filtros ○ blocks ○ qtgui ○ gr: todo lo usado para interconexion de bloques al estilo grc ● El manual más importate es el ​la wiki de gnuradio en Python​, pero, al parecer la documentación más valiosa para nuestro caso es la de ​gnuradio en sphinx​. Al parecer, esa documentación es genérica para c++ y python ● El uso de librerías de gnuradio muchas veces pierde sentido en modo intérprete porque en la mayoría de casos lo que entrega es un objeto. Por ejemplo, si uno necesita una fuente de ruido, eso en gnuradio en un objeto. Toca entrar a estudiar las funciones que ese objeto tiene para poder sacarle provecho. De modo que algo sencillo se puede resolver mejor con un comando que genera números aleatorios.

​9.1.​ Ejemplo 1 de uso de gnuradio por consola Obtener la constelación BPSK >>> from gnuradio import digital >>> x=digital.constellation_bpsk() >>> x

>>> x=digital.constellation_bpsk().points() >>> x ((-1+0j), (1+0j)) >>>

​10.​ números aleatorios

random(): números aleatorios con decimales, pero entre 0 y 1 randrange(A,B): genera números aleatorios entre A y B, pero enteros uniform(): es para cuando se quieren números con decimales. También pueden ser complejos

>>> import random >>> x=random.random() >>> x 0.5189966910063891 >>> x=random.uniform(-1,1) >>> x -0.24443903208713924 >>> x=random.uniform(-1-1j,1+1j) >>> x (-0.573600293514859-0.573600293514859j)

​10.1.​ obtener la amplitud una señal de ruido blanco con gnuradio >>> from gnuradio import analog >>> x=analog.noise_source_f(2,3) >>> x

>>> x.amplitude() 3.0 ## Nota: aqui pudimos obtener la amplitud que ese bloque tiene configurada, pero conocer lo que él genera es algo mayor, quizá requiere el uso de bloques capaces de consumir esa información.

​11.​ Gráficas

Hay varios métodos: ● usando pylab. Es lo más cercano a Matlab. El mejor tutorial es ​este enlace ● matplotlib. Es lo que más hemos usado hasta ahora junto con una sub librería ○ pyplot ○ Ejemplos nuestros

​11.1.​ Trucos de matplotlib.pyplot en 2D ● ● ● ●

importar librería ○ import matplotlib.pyplot as plt hay que imaginar que se trata es de graficar vectores: cada eje de coordenadas es un vector Se usa el comando plot() solo para gráficas 2D, al parecer Para que la gráfica se haga visible es necesario usar show()

>>> import matplotlib.pyplot as plt >>> x=[1,2,3,4,5,6,7,8,9] >>> y=[2,1,3,5,6,3,7,8,5]

>>> plt.plot(x,y) >>> plt.show()

​11.2.​ Trucos matplotlib para gráficas en 3D No las entendemos muy bien, pero hemos creado esta función para facilitarlas def grafica_3D(x,y,z): fig=plt.figure() ax=fig.add_subplot(111, projection='3d') ax.scatter(x, y, z, c='y', marker='o') ax.set_xlabel('x') ax.set_ylabel('y') ax.set_zlabel('z') plt.show()

​12.​ Vectores en python

En python se explotan al máximo las operaciones vectoriales. Consecuentemente ocurre lo mismo con gnuradio. Cuando uno es aprendiz de python surgen muchos interrogantes como: ● Qué relación tienen los vectores con otros conceptos relacionados como ​listas, tuplas,

diccionarios, conjuntos Los asuntos a tener en cuenta son: ●

De manera nativa, para python, las listas y las tuplas son vectores de cualquier cosa, bien sean números, letras o palabras o todo revuelto, no importa qué tipos sean. Las listas se escriben entre paréntesis cuadrados, las tuplas entre paréntesis redondeados. Ejemplos >>> x=("s","d", "gh") >>> x ('s', 'd', 'gh') >>> type(x)

>>> x=["s","d", "gh"]

>>> x ['s', 'd', 'gh'] >>> x=["s","d", "gh", 4, 4.5] >>> x ['s', 'd', 'gh', 4, 4.5] >>> x=["s","d", "gh"] >>> type(x)





Para trabajar con gnuradio no es necesario comprender la diferencia entre tuplas y listas. Son conceptos útiles para las personas que necesitan operar con palabras, letras, diccionarios, etc. Si necesitamos usarlas, usaremos preferiblemente listas. Sin embargo valen las siguientes aclaraciones: ○ las listas abarcan a las tuplas, pero con mayores funcionalidades. ○ Las tuplas son estáticas en su tamaño, las listas son dinámicas ○ Quieres saber más? ​Este es un buen enlace A la hora de realizar operaciones vectoriales o matriciales realmente serias, en realidad se invoca una herramienta llamada numpy. En este sentido lo que hay que tener en cuenta es lo siguiente: ○ lo que numpy maneja son a ​ rreglos​, o en inglés​ arrays​, que equivalen a matrices ○ cuando a una función de numpy se le entrega una lista, ella la convierte a array ○ un vector es un array de una sola fila. Entonces numpy redefine el concepto de vector. Por eso yo hablaré aquí de “numpy vectors” para referirme a lo que numpy entiende por vector. ○ los tipos de números de un array deben ser iguales. Si uno asigna tipos diferentes, el sistema los convierte al tipo que sea más genéricos para los tipos introducidos

>>> import numpy >>> # uno puede definir un vector como una tupla, con numpy se puede traducir en un numpy vector >>> x=(1,4,5.5,6) >>> y=numpy.array(x) >>> y array([ 1. , 4. , 5.5, 6. ]) >>> # se puede definir un numpy vector directamente con numpy >>> a=numpy.array([1,3,4]) >>> a array([1, 3, 4])

​13.​ Trucos de numpy vectors

Ya hemos dicho que por numpy vectors nos referimos a lo que se entiende como vectores desde el punto de vista de numpy. Este ejemplo muestra mejor >>> # Sin numpy lo que se manejan son operaciones de tuplas y listas >>> a=[1,2,3] >>> b=[4,5,6] >>> y=a+b >>> y [1, 2, 3, 4, 5, 6] >>> # Con numpy lo que se manejan son operaciones con arrays (vectoriales y matriciales)

>>> a=numpy.array([1,2,3]) >>> b=numpy.array([4,5,6]) >>> y=a+b >>> y array([5, 7, 9])

​13.1.​ llenar un vector con un número una cantidad de veces  >>> d=numpy.array([5]*4) >>> d array([5, 5, 5, 5]) >>>

​13.2.​ Llenar un vector de ceros  >>> import numpy >>> out=numpy.empty(10) >>> out array([ 2.29886848e-316, 0.00000000e+000, 0.00000000e+000, 0.00000000e+000, 0.00000000e+000, 0.00000000e+000, 0.00000000e+000, 0.00000000e+000, 0.00000000e+000, 0.00000000e+000]) Ojo: lo malo de lo anterior, es que los valores que coloca no son del todo ceros. Lo mejor es >>> import numpy >>> out=numpy.zeros(10) >>> out array([ 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.])

​13.3.​ Llenar un vector con N números aleatorios que oscilan entre  0 y 1  >>> import numpy >>> N=8 >>> x=numpy.random.rand(N) >>> x array([ 0.02540593, 0.46762708, 0.0592303 , 0.65807214, 0.83980549, 0.60138978, 0.85060663, 0.95867215])

​13.4.​ Llenar un vector con N números binarios aleatorios >>> import numpy

>>> N=8 >>> x=numpy.round(numpy.random.rand(N)) >>> x array([ 0., 1., 1., 1., 1., 1., 0., 0.])

​13.5.​ Llenar un vector con N números enteros aleatorios entre 0 y  M  >>> import numpy >>> N=8 >>> M=4 >>> x=numpy.random.randint(0,M,N) >>> x array([2, 3, 0, 3, 0, 1, 2, 1])

  ​13.7.​ Llenar un vector con N números flotantes aleatorios en un rango entre  Mmin y Mmax  >>> import numpy >>> N=8 >>> Mmin=-3.5 >>> Mmin=7. >>> x=numpy.random.uniform(Mmin,Mmax,N) >>> x array([ 4.04588434, -2.61565455, 2.39935915, -1.59059955, -2.94421556, 6.62768384, 1.71561841, 0.45578409])

​13.8.​ Llenar un vector de ceros complejos  >>> import numpy >>> out=numpy.zeros(10,dtype=complex) >>> out array([ 0.+0.j, 0.+0.j, 0.+0.j, 0.+0.j, 0.+0.j, 0.+0.j, 0.+0.j, 0.+0.j, 0.+0.j, 0.+0.j])

​13.9.​ Rebanar un vector, quitándole valores celdas (el diezmado)  >>> import numpy >>> in0=[1,2,3,4,5,6,7,8,9,10] >>> paso=3 >>> out=numpy.empty(4) >>> out[:]=in0[::paso] >>> out array([ 1., 4., 7., 10.]) Ojo: la lógica de esta estrategia es esta: in0[start:end:step]. Lo que hace es analizar el vector desde la casilla start hasta la casilla end, y va rebanando (eliminando o diezmando) step casillas.

​13.10.​ Llenar un vector x con N valores igualmente espaciados  entre un mínimo y un máximo  >>> min=-4 >>> max=4 >>> N=41 >>> x=numpy.linspace(min,max,N) >>> x array([-4. , -3.8, -3.6, -3.4, -3.2, -3. , -2.8, -2.6, -2.4, -2.2, -2. , -1.8, -1.6, -1.4, -1.2, -1. , -0.8, -0.6, -0.4, -0.2, 0. , 0.2, 0.4, 0.6, 0.8, 1. , 1.2, 1.4, 1.6, 1.8, 2. , 2.2, 2.4, 2.6, 2.8, 3. , 3.2, 3.4, 3.6, 3.8, 4. ])

​13.11.​ Llenar un vector con valores incrementados, 0,1,2,3,....  # Esto es lo que no se debe hacer, pues lo que sale es una lista, no un vector >>> n=range(L) >>> n [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] # Esto es lo que hay que hacer; >>> n=np.arange(L) >>> n array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9]) # Nota: fíjese la diferencia entre lista y vector: el segundo apararece entre ([])

​13.12.​ Llenar un array con valores de una función  >>> import numpy >>> x=numpy.linspace(-4,4,41) >>> y=numpy.sinc(x) >>> y array([ -3.89817183e-17, -4.92362781e-02, -8.40918587e-02, -8.90384387e-02, -5.84680802e-02, 3.89817183e-17, 6.68206631e-02, 1.16434881e-01, 1.26137788e-01, 8.50444803e-02, -3.89817183e-17, -1.03943254e-01, -1.89206682e-01, -2.16236208e-01, -1.55914881e-01, 3.89817183e-17, 2.33872321e-01, 5.04551152e-01, 7.56826729e-01, 9.35489284e-01, 1.00000000e+00, 9.35489284e-01, 7.56826729e-01, 5.04551152e-01, 2.33872321e-01, 3.89817183e-17, -1.55914881e-01, -2.16236208e-01, -1.89206682e-01, -1.03943254e-01, -3.89817183e-17, 8.50444803e-02, 1.26137788e-01, 1.16434881e-01, 6.68206631e-02, 3.89817183e-17, -5.84680802e-02, -8.90384387e-02, -8.40918587e-02, -4.92362781e-02, -3.89817183e-17])

​13.13.​ Cambiar periódicamente un paquete de celdas de un vector  por ceros (diezmado al estilo Oppenhein)  >>> import numpy >>> x=[0,1,2,3,4,5,6,7,8,9] >>> paso=3 #Nota: parece que aqui hay un error y es M=3 >>> N=len(x) >>> A=numpy.zeros(N) >>> A[0:N:M]=x[0:N:M] >>> A array([ 0., 0., 0., 3., 0., 0., 6., 0., 0., 9.]) Ojo: A[0:N:M] lo que significa es lo siguiente: los valores del vector, desde la celda 0 hasta la N en pasos de M

​13.14.​ Insertar valores para que ocupen parte de un vector  Como ejemplo vamos a crear una señal cuadrada de 10 muestras donde hay 3 unos seguidos y el resto son 7 ceros. Los unos se ubicarán en las posiciones: 4,5 y 6: >>> x=numpy.empty(10) >>> a=numpy.array([1]*3) >>> x[4:7:1]=a >>> x

array([ 0.00000000e+000, 0.00000000e+000, 0.00000000e+000, 0.00000000e+000, 1.00000000e+000, 1.00000000e+000, 1.00000000e+000, 0.00000000e+000, 0.00000000e+000, 0.00000000e+000])

​13.15.​ Unir o concatenar dos vectores  El caso de las tuplas: h1=(1,1,1) h2=(0,0) h=h1+h2 print h h=(1,1,1,0,0) Pero ojo​, si h1 y h2 son arrays lo que va a ocurrir es una suma punto. Entonces lo que hay que hacer es como lo siguiente: Se desea que x=[0, 0, 0, 0], x1=[1] y que y sea la unión osea y=[0,0,0,0,1] import numpy as np x=np.array(4*[0]) x1=np.array([1]) y=np.concatenate(​(​x,x1​)​) #Nota: fíjese que la notación está entre dos paréntesis Nota: Aunque la segunda opción parece la más apropiada a todas luces en gnuradio, es importante advertir, que muchos bloques, cuando piden un valor vectorial, la opción que brindan son tuplas. Por ejemplo, pruebe usar el bloque “vector source”, al parámentro vector póngale (1,1)+(0,0,0), verá que el entenderá que el vector es 1,1,0,0,0

​13.16.​ crear un vector repitiendo otro N veces  x=np.array([1,2,3,4]) N=23 y=np.tile(x,N) y array([1, 2, 3, 4, 1, 2, 3, 4, 1, 2, 3, 4, 1, 2, 3, 4, 1, 2, 3, 4, 1, 2, 3, 4, 1, 2, 3, 4, 1, 2, 3, 4, 1, 2, 3, 4, 1, 2, 3, 4, 1, 2, 3, 4, 1, 2, 3, 4, 1, 2, 3, 4, 1, 2, 3, 4, 1, 2, 3, 4, 1, 2, 3, 4, 1, 2, 3, 4, 1, 2, 3, 4, 1, 2, 3, 4, 1, 2, 3, 4, 1, 2, 3, 4, 1, 2, 3, 4, 1, 2, 3, 4])

​13.17.​ 12.17.Acortar tamaño de un vector >>> x array([1, 2, 3, 1, 2, 3, 1, 2, 3, 1, 2, 3, 1, 2, 3, 1, 2, 3])

>>> np.resize(x,L) array([1, 2, 3, 1, 2, 3, 1, 2, 3, 1, 2, 3, 1, 2, 3, 1])

​13.18.​ Extraer parte de los datos de un vector >>> x1=np.array([0,1,2,3,4,5,6,7]) >>> y1=x1[2:5] >>> y1 array([2, 3, 4])

​14.​ Trucos de matrices

Nuestros análisis indican que: ● Una matriz puede ser vista como un vector de vectores ● Usualmente los vectores son las filas de la matriz, pero es cuestión de interpretación, pues pueden ser las columnas.

​14.1.​ matrix versus array En numpy se maneja tanto el término array como el de matrix. La primera pregunta que surge es: ¿si los array son tan flexibles como para ser de dimensiones 1D, 2D, 3D, etc, qué necesidad hay de introducir el término matrix?. Primero vemos los siguientes considerandos: ● Estos razonamientos los hemos tomado de este ​enlace​ y las pruebas realizadas para corroborar ● un objeto matrix es una subclase de las numpy arrays. ● Por lo anterior, un objeto matrix hereda los atributos y métodos las arrays ● las numpy matrix son estrictamente de dos dimensiones (2D) a diferencia de las arrays que pueden ser de N dimensiones. ● Las operaciones básicas como multiplicación y quizá algunas más son diferentes en las arrays que en las matrix cuando se aplican de manera directa. Por ejemplo si X1 y Y1 son arrays, X1*Y1 es una multiplicación elemento a elemento, en cambio si X2, Y2 son dos matrices, entonces X2*Y2 es una multiplicación matricial. Ejemplo: >>> x1=np.array([[2,3],[3,5]]) >>> y1=np.array([[1,2],[5,-1]]) >>> x2=np.matrix([[2,3],[3,5]]) >>> y2=np.matrix([[1,2],[5,-1]]) >>> a1=x1*y1 >>> a2=x2*y2 >>> a1 array([[ 2, 6], [15, -5]]) >>> a2

matrix([[17, 1], [28, 1]])



Pese a lo anterior, con las arrays se pueden hacer operaciones propias de las matrices, solo que no de manera tan directa. Por ejemplo, la multiplicación sería de la siguiente manera

>>> a1=np.matmul(x1,y1) >>> a1 array([[17, 1], [28, 1]]) ●

Hay que tener en cuenta que las señales que se manejan en gnuradio son tipo arrays, no tipo matrix. Por ejemplo, si un bloque de gnuradio tiene 5 señales de entrada y cada una un vector de 4 elementos, en cierto instante se podría tener una señal como la siguiente:

>>> in0 array([[0, 1, 2, 3], [2, 3, 4, 5], [3, 4, 5, 6], [4, 5, 6, 7], [5, 6, 7, 8]]) En ese caso, los siguientes comandos son útiles: >>> L=inn0.shape >>> L (5, 4) >>> L[0] # numero de senales 5 >>> L[1] # tamano de los vectores de cada senal 4 >>> in0.mean(0) # la senal promedio array([ 2.8, 3.8, 4.8, 5.8])

​14.2.​ Principales comandos Importar librerías ● import numpy as np Crear un array >>> a=np.array(([1,2,3,4],[5,6,7,8],[9,10,11,12],[13,14,15,16])) >>> a

array([[ 1, 2, 3, 4], [ 5, 6, 7, 8], [ 9, 10, 11, 12], [13, 14, 15, 16]])

Imprimir un vector fila, por ejemplo el 4to vector >>> a[3] array([13, 14, 15, 16])

Imprimir un vector columna, por ejemplo el 4to vector >>> a[:,3] array([ 4, 8, 12, 16])

transponer una matriz >>> a_t=np.transpose(a) >>> a_t array([[ 1, 5, 9, 13], [ 2, 6, 10, 14], [ 3, 7, 11, 15], [ 4, 8, 12, 16]])

​14.3.​ Convertir un array 2D en uno 1D >>> data = np.array([[1,2,3], [4,5,6], [7,8,9]]) >>> data array([[1, 2, 3], [4, 5, 6], [7, 8, 9]]) >>> L=len(data) >>> L 3 >>> y=data.reshape(-1) >>> y array([1, 2, 3, 4, 5, 6, 7, 8, 9]) >>> L=len(y) >>> L 9

​15.​ Programación científica ​15.1.​ La Matriz de covarianza en matemáticas Supongamos el siguiente experimento: nos paramos a la puesta de nuestra casa y a todo el que pasa medimos la altura X y preguntamos la edad Y. Entonces podemos obtener algo así como: X=[1.7, 1.6, ….] Y=[18, 35, ...] Obviamente X y Y guardan correlación La covarianza de X con ella misma es: Cov X = E [(X − μX )(X − μX )] La covarianza de Y con ella misma es: Cov Y = E [(Y − μY )(Y − μY )] La covarianza de X con Y es: Cov X,Y = E [(X − μX )(Y − μY )] La covarianza de Y con X es: Cov Y ,X = E [(Y − μY )(X − μX )] La matriz de convarianza de X,Y (también se conoce como matriz de coeficientes de correlación) es Cov X,X

Cov X,Y

Cov Y ,X

Cov Y ,Y

​15.2.​ la matriz de covarianza en python Veámoslo mediante el siguiente ejemplo: ● Tenemos 3 variables x0,x1,x2 y cada contiene 5 observaciones: x1=​0.1​, ​0.3​, ​0.4​, ​0.8​, ​0.9 x2=​3.2​, ​2.4​, ​2.4​, ​0.1​, ​5.5 x3=​10.​, ​8.2​, ​4.3​, ​2.6​, ​0.9 ● Los organizamos en forma de matriz X​ ​=​ ​np.array​([ [​0.1​, ​0.3​, ​0.4​, ​0.8​, ​0.9​], [​3.2​, ​2.4​, ​2.4​, ​0.1​, ​5.5​], [​10.​, ​8.2​, ​4.3​, ​2.6​, ​0.9​] ])



Hallamos la covarianza

print​( ​np.cov​(​X​) ) ​0.115​ ,

​0.0575​,

​-​1.2325​],

[ ​-​1.2325​,

​-​0.8775​,

​14.525​ ]]

[[ [

​0.0575​,

​3.757​ ,

​-​0.8775​],

​16.​ Instalación de librerías adicionales $ python -V: Las librerias dependen de la versión de python. con este comando podemos saber la versión que tenemos instalada libreria matplotlib: ● mi version de pyhton es la 2.7.12. La instalación la hice simplemente así: ○ $ sudo apt-get install python-matplotlib ● las nuevas versiones de python son 3.x.x.x. La instalción es algo así como: ○ $ sudo apt-get install python3-matplotlib

​17.​ Graficar con Matplotlib ​17.1.​ Gráfica de tiempo real tipo osciloscopio El problema de matplotlib es que lo más usado son las gráficas estáticas. Cuando el asunto gira entorno a gráficas cambiante, en tiempo real, la cosa se complica. la solución que hemos encontrado es el uso de drawnow. Preparativos: ● previamente se instala drawnow así $ pip install drawnow Este es un ejemplo: import matplotlib import matplotlib.pyplot as plt import numpy as np from drawnow import * plt.ion() def makeFig(): t = np.arange(0,2, 0.01)

s=np.random.rand(200) plt.plot(t, s) while True: drawnow(makeFig) plt.pause(1)

Otra opción es usar FuncAnimation como en este ejemplo. pero aquí el truco es que FuncAnimation crea un ciclo infinito, como el while anterior import matplotlib import matplotlib.pyplot as plt import matplotlib.animation as animation from matplotlib import style import numpy as np

def makeFig(i): t = np.arange(0,2, 0.01) s=np.random.rand(200) ax1.clear() ax1.plot(t, s) fig=plt.figure() ax1=fig.add_subplot(1,1,1) ani=animation.FuncAnimation(fig,makeFig,interval=1000) plt.show()