Está en la página 1de 154

PYTHON

Este instructivo es para ser usado para practicar con un Python


instalado

Python es un lenguaje de programación de alto nivel, orientado a


objetos, diseñado para ser fácil de programar y fácil de leer.

Características

- Lenguaje de propósito general


Python es un lenguaje de programación de propósito general. Ello
significa que se puede usar para crear programas de aplicaciones muy
diversas, como cálculo numérico, manejo de bases de datos, juegos,
internet, sonido, video, imágenes, etc:
https://en.wikipedia.org/wiki/List_of_Python_software

No es especializado, como por ejemplo, Matlab y Octave en cálculo


numérico o Maxima, Maple y Mathematica en álgebra computacional.
Aunque el conjunto de instrucciones y objetos básicos de Python es
relativamente reducido, es posible ampliarlo enormemente con módulos
dedicados a un determinado tema:
https://pypi.python.org/pypi

- Tipos dinámicos.
Significa que un objeto definido inicialmente de un determinado tipo,
puede cambiar durante la ejecución de un programa.
Por ejemplo, una variable escalar que inicialmente es tipo entero,
puede cambiar a tipo punto flotante, o a lógica o cadena de
caracteres en el transcurso de la ejecución.
Esto contrasta con lenguajes como C, C++ donde todas las variables,
constantes, objetos deben tener un tipo predefinido antes de ser
referenciadas y además no puede cambiar.
Aunque los tipos dinámicos pueden considerarse generalmente una
ventaja, dificultan la creación de un compilador para el lenguaje.

- Principalmente interpretado
Con frecuencia se dice que la principal realización de Python es
mediante un intérprete. Un intérprete es un programa que lee una
instrucción del programa fuente, la traduce a lenguaje máquina, la
ejecuta, lee la siguiente instrucción, etc.
En la actualidad pocos lenguajes se realizan estrictamente mediante
interpretación (Bash, AWK, sed, bc, cmd). En realidad, en Python,
JavaScript, PHP, Perl, Tcl, Ruby, Basic, R, Octave y otros lenguajes,
la principal realización es mixta: tienen una parte de compilación y
una parte de interpretación.
En el caso de Python, en una primera etapa todo el código fuente es
compilado a un lenguaje de "bytecodes" o lenguaje de máquina virtual,
el cual es independiente del hardware y del sistema operativo donde
eventualmente se ejecutará. Además, el código resultante ha pasado
una primera validación de sintaxis y dependencias.
El programa en código de máquina virtual permanece en memoria RAM y
entonces es interpretado (traducido) instrucción a instrucción a
código máquina, y ejecutado de inmediato. Sólo las instrucciones
bytecodes que es necesario ejecutar se traducen a lenguaje máquina.
El código compilado en bytecodes puede ser salvado en un archivo con
extensión .pyc, por lo que en la próxima ejecución del programa no
será necesaria la etapa de compilación.

Existen realizaciónes de Python con compilador JIT, por ejemplo PyPy.


http://pypy.org/
Pypy compila primero a bytecodes. Después, el intérprete analiza por
adelantado las instrucciones a ejecutar y compila los bytecodes a
código máquina, en particular lazos de iteración y funciones. Pero
además, este código compilado se mantiene en memoria rápida (caché) y
es ejecutado cada vez que se requiera.
Aunque la ejecución de programas con Pypy es mucho mas rápida, no
resulta de mucha utilidad para aplicaciones de cálculo numérico en
Ingeniería, Estadística y Ciencias debido a que por el momento no
puede aplicar JIT a los módulos numéricos Numpy de Python. Además
sólo soporta la versión 2.7 de Python.

También existen "compiladores" para Python, por ejemplo Nuitka,


http://nuitka.net/pages/overview.html y Shed Skin
http://shedskin.github.io/
Éstos, en realidad primero convierten el programa de lenguaje Python
a lenguaje C++ y después compilan el código C++. Estrictamente no
compilan directamente de Python a lenguaje máquina.

Otra alternativa para aumentar la rapidez de ejecución es usar Numba,


el cual puede compilar las partes del código Python de mayor tiempo
de cómputo a código máquina en modo JIT o en estático de antemano.
http://numba.pydata.org/

- Enlaces con otros lenguajes


Python facilita mucho la interrelación con otros lenguajes de
programación. Por ejemplo, es posible ejecutar código compilado de
C, C++ (con Cython, Weave), o Fortran (con f2py) como si fuesen
módulos de Python.

- Versiones
Existen dos versiones principales de Python: hasta la versión 2.7 y
la 3.0 o mayor.
Las versiones menores que 3.0 no son mantenidas y deberían
desaparecer en el futuro; pero todavía hay paquetes y programas que
no han sido portados de la versión 2.7 a las versiones 3.

Sitio oficial de Python en la red:


https://www.python.org/

Descargas:
https://www.python.org/downloads/
Instalación en Windows
Python 3.4.0
Distribución Pyzo de Python:
http://www.pyzo.org/
Integra Python 3, Ipython, Anaconda y un IDE (IEP)

1- Descargar el instalador de 32 o 64 bits de la distribución Pyzo,


la cual incluye Python 3, paquetes numéricos y científicos y un
ambiente de desarrollo integrado con ventanas para el shell Ipython,
editor IEP, navegador de archivos, bitácora, historial:
http://www.pyzo.org/downloads.html

También es conveniente instalar las fuentes de letra DejaVu Sans


Mono. Se bajan desde:
http://sourceforge.net/projects/dejavu/
El instructivo para instalarlas está mas abajo.

2- Ejecutar el instalador, por ejemplo: pyzo_distro-2015a.win64.exe


(64 bits).
Python quedará instalado en:
C:\pyzo2015a
En el escritorio pondrá el ícono de Pyzo

3- Crear, -si no se tiene ya de una versión anterior de Python- un


directorio de trabajo para Python, preferiblemente en el directorio
del usuario, por ejemplo:
C:\Users\PC\Python (Nota: esta ruta es sólo un ejemplo)

4- En el escritorio, hacer click botón derecho sobre el ícono de


Python --> Propiedades --> Iniciar en: C:\Users\PC\Python --> Aceptar

5- Para iniciar Pyzo: doble click sobre el ícono en el escritorio.


Iniciará con un instructivo breve de uso.

Configuración de Pyzo
6- Doble click sobre el ícono de Pyzo. Aparecerá un ambiente de
trabajo con 4 ventanas: el shell Ipython, el editor IEP, el navegador
de archivos y el árbol de funciones.
Se pueden abrir/cerrar otras ventanas en el menú con: Herramientas
(Tools)

Configurar el idioma:
Settings --> Select language --> Spanish --> OK
File --> Quit IEP
Volver a iniciar Pyzo

Configurar el tipo de letra:


Ver --> Fuente --> DejaVu Sans Mono (recomendada)
Si no tiene instalada la fuente DejaVu Sans Mono en Windows, mas
abajo se indica como instalarla.

Configuración cónsola:
Cónsola --> Edita configuración cónsola --> exe:
C:\pyzo2015a\python.exe --> ipython: seleccionar la casilla -->
DirInicio: C:\Users\PC\Python --> Done

Configuración de colores:
Con un editor de texto como notepad, o el propio editor de Pyzo
abrir:
C:\pyzo2015a\Lib\site-packages\iep\codeeditor\base.py

a partir de la línea 234, agregar y reemplazar por lo siguiente,


manteniendo la sangría existente en base.py:

grisobscuro = "#3C3C3C"
S = {}
S["Editor.text"] = "back: black, fore: YellowGreen"
S['Syntax.identifier'] = "fore: Peru, bold:no, italic:no,
underline:no"
S["Syntax.nonidentifier"] = "fore: blue, bold:no, italic:no,
underline:no"
S["Syntax.keyword"] = "fore: blue, bold:yes, italic:no, underline:no"
S["Syntax.functionname"] = "fore: Purple, bold:yes, italic:no,
underline:no"
S["Syntax.classname"] = "fore: magenta, bold:yes, italic:no,
underline:no"
S["Syntax.string"] = "fore: red, bold:no, italic:no, underline:no"
S["Syntax.unterminatedstring"] = "fore: red, bold:no, italic:no,
underline:dotted"
S["Syntax.python.multilinestring"] = "fore: red, bold:no, italic:no,
underline:no"
S["Syntax.number"] = "fore: dark orange, bold:no, italic:no,
underline:no"
S["Syntax.comment"] ="fore: green, bold:no, italic:yes, underline:no"
S["Syntax.todocomment"] = "fore: magenta, bold:no, italic:yes,
underline:no"
S["Syntax.python.cellcomment"] = "fore: green, bold:yes, italic:no,
underline:full"
S["Editor.Long line indicator"] = "linestyle:solid, fore: dark grey"
S["Editor.Highlight current line"] = "back: %s" % grisobscuro
S["Editor.Indentation guides"] = "linestyle:solid, fore: light grey"
S["Editor.Line numbers"] = "back: light grey, fore: black"

Salvar, salir, cerrar y volver a iniciar Pyzo


Dado el código de un color, ver en monitor dicho color:
http://rgb.to/
Otros ambientes de desarrollo para Python:

SPYDER
Es una alternativa a Pyzo, aunque puede ser conveniente instalar
primero Pyzo y después Spyder. Al igual que Pyzo, integra un ambiente
de programación con editor, shell, depurador, lista de objetos, etc.
Tiene un instalador para Windows.
https://github.com/spyder-ide/spyder

PyCharm edu
Ambiente de desarrollo para Python en Linux, Windows y OS X
https://www.jetbrains.com/pycharm-edu/

ERIC
Ambiente de desarrollo para Python en Windows y Linux
http://eric-ide.python-projects.org/

PYPE
Ambiente de desarrollo para Python en Windows y Linux. Conveniente
instalar primero Pyzo.
http://pype.sourceforge.net/index.shtml

Instalación fuentes DejaVu Sans Mono Windows


Estas fuentes son muy convenientes porque permiten distinguir mejor
ciertos caracteres, sobre todo cuando se programa o se crean archivos
de datos que contienen letras y números.
Si en la fuente que usa actualmente -por ejemplo: Calibrí, Courier,
Times New Roman, casi todas las sans serif- no identifica de
inmediato los siguientes caracteres:

1lI|

entonces mejor utilize DejaVu Sans Mono

Si no tiene instaladas estas fuentes puede descargar el paquete


desde:

http://sourceforge.net/projects/dejavu/

Descomprimir los archivos en un directorio


Ir al subdirectorio descomprimido:
dejavu-fonts-2.34/ttf

Instalación:

Forma 1:
Seleccionar y hacer click botón derecho sobre los archivos con
extensión .ttf
En el menú aparecerá la opción instalar

--------------
Forma 2:
Panel de Control -->
Fonts (Dejar abierta esa ventana) -->
Desde un navegador de archivos seleccionar las fuentes DejaVu .ttf y
arrastrarlas a la ventana de fonts. Las instala automáticamente.

--------------

Para usarlas hay que seleccionarlas en cada programa, como Word,


Notepad, Octave, Pyzo, etc.
Para activarlas en Pyzo:
Ver --> Fuente --> DejaVu Sans Mono
Paquetes Python

Existen varias formas de instalar y desinstalar paquetes Python:


- Con el programa Conda de Anaconda
- Con el programa PIP
- Manualmente en archivos tar o zip
- En directorios con módulos del usuario

CONDA
Programa manejador de paquetes de Anaconda https://www.continuum.io/
Lista, busca, instala, actualiza, desinstala, etc, paquetes Python.
Viene con la distribución Pyzo.

Lista de paquetes de Anaconda


http://docs.continuum.io/anaconda/pkg-docs#python-3-4

Directorio de paquetes Python de Anaconda instalados con Pyzo:


C:\pyzo2015a\pkgs

Conda se puede usar desde el shell de Python en Pyzo, pero cuando se


trata de instalar, actualizar, etc, advierte que es conveniente
cerrar todos los programas que usan Python, entre ellos Pyzo.
Entonces cerrar Pyzo y usar alguna de las siguientes alternativas:

Forma 1:
Abrir un terminal DOS
Ejecutar: C:\pyzo2015a\Scripts\conda.exe con los argumentos indicados
mas adelante

Forma 2:
Con FreeCommanderXE: Ir a C:\pyzo2015a\Scripts --> Ctrl D ó Tools -->
DOS box
Ejecutar: conda.exe con los argumentos indicados mas adelante

Forma 3:
Abrir una cónsola de Ipython ejecutando:
C:\pyzo2015a\ipython_qtconsole.exe
ó
C:\pyzo2015a\ipython_notebook.exe
En el shell ejecutar conda.exe con los argumentos indicados mas
adelante

Operaciones mas usuales con Conda:


Ayuda: conda -h ó conda help
Listar paquetes instalados: conda list
Buscar un paquete conda search paquete
Instalar paquete conda install paquete
Actualizar paquete conda update paquete
Cuando instala un paquete también actualiza todos los demás paquetes

conda search paquete buscará en Internet la versión mas reciente


de paquete
conda search buscará en Internet todos los paquetes todas
las versiones
conda update actualizará todos los paquetes
conda info entre las cosas que informa está una lista
de direcciones de red donde busca y baja los
paquetes

PIP
Utilidad para buscar, bajar, instalar, desinstalar paquetes del
repositorio pypi de Python.org, el cual contiene mas de 70000
paquetes:
https://pypi.python.org/pypi

El programa pip se encuentra en la carpeta: C:\pyzo2015a\Scripts


Se puede invocar desde el shell de Python o desde un terminal cmd de
Windows.

Ejemplo:

pip help Ayuda para uso de pip

pip search seismic busca paquetes en pypi que contengan


referencia a la palabra "seismic".
Nota: es mejor buscar directamente en el
sitio web con un navegador

pip install segpy baja e instala el paquete segpy para leer y


escribir registros sísmicos en formago SEGY

Instalación manual de paquetes


Bajar el paquete comprimido, usualmente en tar.gz o zip, y
descomprimirlo en una subcarpeta de C:\pyzo2015a\Lib\site-packages
con el nombre del paquete.
Algunos paquetes traen un programa instalador escrito en Python
denominado: setup.py
En una ventana cmd de Windows, cambiarse a la carpeta donde está
setup.py
Para ejecutar el instalador hacer:
C:\pyzo2015a\python setup.py install
Paquetes del usuario
Se pueden instalar en cualquier directorio que se incluya en la lista
de ruta de búsqueda de Python (import sys; sys.path).
Un paquete tiene el mismo nombre que la carpeta o directorio que lo
contiene
La carpeta del paquete contiene archivos de módulos, ejecutables
compilados, bibliotecas, etc. Python reconoce cada módulo por el
nombre del archivo con extensión .py
No es indispensable, pero si conveniente, que esta carpeta contenga
un archivo denominado: "__init__.py", el cual puede estar vacío.
A su vez cada archivo de módulo contiene funciones Python.

Distribuciones científicas de Python


Anaconda (Linux, Windows, Mc OS X - Python 3.x)
https://www.continuum.io/

Winpython (Windows - Python 3.x)


https://winpython.github.io/

Python(x,y) (Windows - Python 2.7)


http://python-xy.github.io/
Información en la red
Python
Documentos, tutoriales:
https://docs.python.org/3/

Biblioteca de funciones:
https://docs.python.org/3/library/index.html

Lista de paquetes:
https://pypi.python.org/pypi

Tutoriales Python:
http://www.python-course.eu/index.php
http://kestrel.nmt.edu/~raymond/software/python_notes/index.htm
http://showmedo.com/videotutorials/python
http://www.swaroopch.com/notes/python/

Tutorial scipy:
http://scipy-lectures.github.io/index

Curso en línea Universidad de Alicante:


https://www.youtube.com/playlist?list=PLoGFizEtm_6iheDXw2-
8onKClyxgstBO1

Pyzo
http://www.pyzo.org/

Spyder
https://github.com/spyder-ide/spyder

Anaconda
http://continuum.io/
http://docs.continuum.io/anaconda/pkg-docs#python-3-4

Matplotlib
http://matplotlib.org/index.html
http://matplotlib.org/users/pyplot_tutorial.html
http://matplotlib.org/users/image_tutorial.html
http://matplotlib.org/users/index_text.html

Mayavi
http://docs.enthought.com/mayavi/mayavi/index.html

Mpmath
http://mpmath.org/
http://mpmath.org/doc/current/
Gmpy2
https://gmpy2.readthedocs.org/en/latest/
https://code.google.com/p/gmpy/downloads/list

Numpy
http://kestrel.nmt.edu/~raymond/software/python_notes/paper003.html
http://scipy.github.io/old-wiki/pages/Numpy_Example_List

Scipy
http://scipy-lectures.github.io/intro/scipy.html
http://docs.scipy.org/doc/scipy/reference/linalg.html#scipy.linalg
http://docs.scipy.org/doc/numpy/genindex

Numba
http://numba.pydata.org/

Cython
http://cython.org/

Weave
http://docs.scipy.org/doc/scipy/reference/tutorial/weave.html

f2py
http://docs.scipy.org/doc/numpy/f2py/index.html

Ayuda sobre funciones y objetos de Python


Ejemplos. En el shell Ipython escribir:
help(3)  ayuda sobre objetos clase entero
help(3.2)  ayuda sobre objetos clase real
help(pow)  ayuda sobre la función pow
pow?  ayuda sobre la función pow
help(mifuncion)  ayuda sobre función definida por el usuario

Manual de Python
Se encuentra en el siguiente directorio de Windows:
C:\pyzo2015a\Doc\python342.chm

Python con Ipython Notebook


Forma 1
Ejecutar:
C:\pyzo2015a\ipython_notebook.exe
Forma 2
Con el explorador de archivos o FreeCommander ir a:
C:\pyzo2015a\
y en la barra de comandos escribir:
ipython notebook (enter)
Lanzará un servidor http local, conectará con el navegador y abrirá
una página web:
http://localhost:8888/tree

Desde esta página se pueden crear "notebooks", que son documentos que
pueden contener una mezcla de instrucciones Python, resultados, texto
de comentarios, imágenes.

Para crear un nuevo notebook:


Click en el botón "New Notebook" situado en la parte superior derecha
de la página inicial.
Requiere tener activado javascript, y conexión a Internet para
disponer de símbolos matemáticos.

Correr Python sin instalarlo


Existe un servicio de edición y ejecución de programas para diversos
lenguajes de programación mediante un servidor en Internet:

https://www.python.org/shell/
http://www.tutorialspoint.com/codingground.htm
http://www.tutorialspoint.com/execute_python3_online.php
https://ideone.com/

Los programas se corren en el servidor, no localmente.


Por ello se requiere conexión a Internet.
Puede no resultar apropiado por el tiempo de subida y bajada si el
programa se destina a procesar archivos de datos grandes.
También limitan el tiempo de conexión.
Editores ascii
Para crear y editar guiones de Python se debe utilizar un editor de
texto ascii, preferiblemente diseñado para programación.
Si se utiliza un editor con formato, por ejemplo Word, WordPad, el
archivo debe guardarse en modo texto, con extensión .py

Si instaló Pyzo, éste ya trae incorporado el editor IEP que es


bastante bueno y permite la ejecución directa de los guiones Python.
Sin embargo, carece de ciertas características útiles, como la
comprobación de cierre de paréntesis.

Lista de editores para Python:


https://wiki.python.org/moin/PythonEditors

Otros editores de texto:

Notepad++ (Windows, Linux a través de Wine)


http://notepad-plus-plus.org/

RText (Windows, Linux, OS X)


http://fifesoft.com/rtext/

Editra (Windows, Linux, OS X)


http://editra.org/

SciTE (Windows, Linux)


http://www.scintilla.org/SciTE.html

AkelPad (Windows)
http://akelpad.sourceforge.net/en/index.php

CUTE (Linux)
http://cute.sourceforge.net/features.html
Python como calculadora

El shell de Python se puede usar directamente como calculadora, con


operaciones aritméticas ordinarias sobre escalares reales o
complejos: + - * / // ** %
Se escribe la operación y se finaliza con enter:
3+2  5
15*3-8/2+1  42

_ es una variable que guarda siempre el resultado de la operación más


reciente. Se muestra escribiendo _ y enter, o con print(_)

Las operaciones siguen la precedencia usual. En el ejemplo, primero


se calculan la multiplicación y la división y después la suma y la
resta.
Si se desea cambiar esta precedencia es necesario colocar paréntesis.
Por ejemplo:
15*(3-8)/(2+1)  -25
10/(6+4)/2  0.5 equivale a: 10/10/2=(10/10)/2
10/((6+4)/2)  2

La exponenciación se representa con dos asteriscos:


3**4  81
9**(1/2)  3.0
-1**(1/2)  -1 (resultado inesperado en Python, R, Octave, Julia)
(-1)**1/2  -0.5 (interpreta que el exponente es 1, no 1/2)
(-1)**(1/2)  (6.123233995736766e-17+1j) (paréntesis a la base)
2**2**3  256 (equivale a: 2**(2**3)) (Python, R, Julia)

División con decimales y truncada:


5/2  2.5 división normal
5//2  2 división truncada, entero(a partir de Python 3)
3.9//1  3.0 división truncada, real

Residuo de división:
7%4  3
7.6%3.2  1.1999999999999993

Complejos:
(3+4j)**(1+0.5j)  (-0.5048246889783181+3.104144076995529j)

Métodos y propiedades
En Python todas las variables, constantes y funciones son objetos,
que pueden tener atributos. En Python los métodos también se
denominan atributos.
Los atributos de un objeto se invocan con la siguiente sintaxis:
objeto.metodo(argumentos) para métodos (funciones del objeto)
objeto.propiedad para propiedades (valores)
La lista de atributos que tiene un objeto se puede obtener con la
función dir.
Por ejemplo:
dir(x) métodos y atributos de la variable x
dir(4.5) métodos y atributos de la constante 4.5
dir(abs) métodos y atributos de la función abs
abs.__dir__() métodos y atributos de la función abs
También se puede determinar si un objeto tiene un atributo particular
mediante la función hasattr:
hasattr(4.5,"__abs__")  True
hasattr(4.5,"add")  False

Funciones y métodos
En esencia son lo mismo, pero en Python se acostumbra denominar
funciones a los miembros pertenecientes a un módulo (equivalente a
una biblioteca de funciones) o las elaboradas por el usuario. Se
denomina métodos a las funciones pertenecientes a un objeto creado en
el shell de Python o en un programa.
Todos los métodos son funciones, pero no todas las funciones son
métodos porque éstos están asociados a algún objeto.
Una función es independiente de un objeto (aunque en Python un módulo
es también un objeto), mientras que el método depende del objeto.
Esto implica que para usar un método debe existir primero el objeto
que lo contiene.
Con una función es necesario especificar sus argumentos. Con un
método, el objeto forma parte implícitamente de los argumentos. Por
ejemplo:
abs(-3.4)  3.4 (función abs, argumento: -3.4)
(-3.4).__abs__()  3.4 (el arguménto implícito de __abs__() es -3.4)
Si un objeto tiene un método, dicho método aplica sólo a esa clase de
objeto; en cambio, una función puede aplicar a mas de una clase de
objeto
Por ejemplo, la función reshape y el método reshape de numpy.
La función reshape se puede aplicar a un arreglo numpy, a una lista o
una tupla.
Un arreglo numpy también tiene el método reshape, pero las listas y
las tuplas no lo tienen. Es decir, para redimensionar un arreglo
numpy se puede usar el método reshape del arreglo o la función
reshape, pero para listas y tuplas sólo se puede hacer con la función
reshape.
Existen métodos y funciones que realizan exactamente la misma tarea.
Por ejemplo: la función abs y el método __abs__ .
Cuando se da tal caso, los programadores expertos de Python suelen
recomendar utilizar preferiblemente el método asociado al objeto (en
el ejemplo, utilizar __abs__(); sin embargo, si el criterio para
elegir es el tiempo de ejecución, entonces es recomendable probar con
el comando mágico timeit de Ipython para decidir. Por ejemplo, len(x)
es mas rápida que x.__len__().
Los métodos con nombre entre dos pares de guiones bajos como __abs__,
__len__, etc, por convención en Python indican que existe una
correspondiente función, operador o propiedad con igual nombre sin
los guiones, tales como abs() y len(). Esto puede servirle de
advertencia al usuario para no crear una función con igual nombre.

Funciones matemáticas básicas


Las funciones matemáticas de Python en la biblioteca base sobre
escalares o complejos son muy pocas:
abs(3-4j)  5.0 obtener magnitud de número real o complejo
(3-4j).__abs__()  5.0 magnitud de número real o complejo
(3-4j).conjugate  (3+4j) conjugado de número complejo
complex(2,7)  (2,7j) formar número complejo
round(3.9)  4 redondear real al entero mas cercano
pow(3.1,2.5) elevar a potencia, equivalente a 3.1**2.5
sum([2,3,5,7])  17 sumatoria de sucesión de números

Variables
Se forman por asignación directa o como resultado de alguna operación
o función.
El nombre de una variable sólo puede contener letras y números. No
puede comenzar con un número. Python diferencia entre mayúsculas y
minúsculas.

casipi=3.1416
x3=9.4*5.1-43.8
Xr=Yr=Zr=round(12.7)
x,y,z=14,’perro’,5+7j x  14, y  ’perro’, z  (5+7j)

Lista de palabras reservadas en Python 3.4 que no deben usarse para


definir objetos (variables, funciones, clases).

Palabras reservadas en Python


and del from None True
as elif global nonlocal try
assert else if not while
break except import or with
class False in pass yield
continue finally is raise
def for lambda return

La lista de funciones y propiedades básicas se obtiene con:


dir(__builtins__).
Además de éstas, es conveniente evitar usar las utilizadas como
funciones en módulos importados completos. Por ejemplo si se importa
el módulo math, con: from math import * entonces se deben evitar
sqrt, exp, log, ..., etc
Tipos
Átomos o escalares (indivisibles)
Numéricos, caracteres, lógicos y None
-76.4, "k", "2", "&", True, False, None

Numéricos:
Enteros, punto flotante, complejos

Enteros
De forma predeterminada utiliza 64 bits, pero en Python 3 el tamaño
de los enteros sólo está limitado por la memoria disponible.
Ejemplo: 10**100 es aceptable

La función int convierte a entero si es aceptable (truncando)


int(23.6) --> 23 flotante a entero, trunca decimales
int("23") --> 23 cadena de caracteres a entero
int("23.6") --> error cadena de caracteres a entero no válida
int(True) --> 1 conversión lógico a entero

En una operación aritmética donde todos los operandos son enteros y


los operaciones son suma, resta, multiplicación, exponenciación
entera y residuo, el resultado es un entero.
Si la operación involucra una división o exponente punto flotante, el
resultado será punto flotante (aunque matemáticamente resulte un
entero).
Ejemplos:
9+3*2-25%3**2 --> 8 (entero)
6/1 --> 6.0 (punto flotante)
6//1 --> 6 (entero, división truncada)
4**(3/2) --> 8.0 (punto flotante)

Punto flotante
De forma predeterminada son de 64 bits. Sin embargo con las funciones
del módulo numpy se pueden fijar en 16 o 32 bits.
Los rangos de valores, dígitos, precisión, etc se pueden obtener
con funciones del módulo numpy.
Se puede tener números punto flotante de precisión arbitraria con las
funciones de los módulos mpmath o gmpy2.
Otros de precisión arbitraria no tan completos: decimal, bigfloat,
pyGMP

import numpy
print(numpy.finfo(numpy.float))

La función float convierte a flotante si es válida la conversión.


float(25) --> 25.0 entero a flotante
float("25.7") --> 25.7 cadena a flotante
float("1.56e3") --> 1560.0 cadena a flotante
float("a48.4") --> error, no es posible convertir cadena a flotante
float(True) --> 1.0 lógico a flotante

Complejos
Formados por parejas de números punto flotante. Por lo tanto, de
forma predeterminada cada complejo ocupa 128 bits (64+64).
Los complejos se representan mediante suma algebraica, multiplicando
por J o j la parte imaginaria.
3-4j parte real 3, parte imaginaria -4
1j parte real 0, parte imaginaria 1
3.2+0j parte real 3.2 parte imaginaria 0 (forzando a complejo)

La función complex convierte a complejo, si es válida la conversión


complex(3,-4) --> (3-4j) enteros a complejo
complex("3-4j") --> (3-4j) cadena de caracteres a complejo
complex(True) --> (1+0j) lógico a complejo

Caracteres
Son los átomos de las cadenas de caracteres. Sin embargo, Python no
tiene el tipo character como otros lenguajes. En Python un caracter
es sólo una cadena (str) de un solo elemento.

Lógicos
Sólo tienen dos valores True y False.
La función bool convierte a lógico.
Números entero, flotante y complejo cero convierten a False. También
contenedores como cadenas, listas, tuplas, conjuntos y diccionarios
vacíos convierten a False. Todo lo demás convierte a True.
bool(0)  False
bool(0.0)  False
bool("")  False
bool(None)  False
bool([])  False
bool("abc")  True
bool("False")  True
bool("0")  True
bool(3.49)  True

Algunos métodos de escalares

(-3+4j).__abs__()  5 obtiene la magnitud


(51-17j).real()  51 obtiene parte real
x=2.7
x.__sizeof__()  24 tamaño del objeto en bytes
x.__bool__()  True lógico de x

None
Sólo tiene el valor None.
Puede usarse para inicializar variables sin ningún valor.
Si una función no retorna ningún otro objeto, entonces retorna None.
En una función, si algún argumento opcional no es especificado, éste
puede pasar el valor None a la misma.

Contenedores
Son objetos que representan colecciones de objetos, tales como
escalares, funciones y/o otros contenedores. Por ejemplo, una lista o
una cadena de caracteres son casos particulares de contenedores.
Los elementos en un contenedor pueden ser todos del mismo tipo o de
diferentes tipos.
Los principales contenedores son: cadenas ascii, bytes, bytearrays,
listas, tuplas, conjuntos y diccionarios.
Pero existen mas contenedores definidos en otros módulos,
particularmente en el módulo collections

Suma de contenedores y multiplicación de contenedor por entero


Los operadores + y * son operadores de concatenación con los
contenedores listas, tuplas, cadenas de caracteres y bytes.
Se comportan de la forma aritmética sólo con escalaes numéricos y con
arreglos numéricos de numpy.

Ejemplos:
[2,3,5,7]+[11,13] --> [2,3,5,7,11,13]
[2,3,5,7]*3 --> [2,3,5,7,2,3,5,7,2,3,5,7]
"¡Oh, oh!." + " Me parece haber visto" + " un lindo gatito"
print(80*"-")

Para realizar operaciones de suma y multiplicación algebraica de


arreglos numéricos se pueden utilizar las funciones del módulo numpy
o utilizar ciclos for o while que realizen la operación elemento a
elemento o unas formas particulares de Python denominadas
comprensiones y mapas.

Principales propiedades de contenedores


Todos los contenedores son iterables en sus elementos, por ejemplo en
lazos for, while, con la instrucción "in" (for x in A:)

La mayoría son indexables, lo que permite hacer referencia a algún


elemento particular del arreglo mediante un índice. Los conjuntos no
son indexables.

La mayoría son numerables, lo que permite indexarlos mediante números


enteros. Esto además establece un orden en los elementos del
contenedor. Los diccionarios son indexables, pero no numerables, sus
elementos no tienen un orden particular.

Los contenedores que poseen el método __add__() son concatenables y


también se puede usar los operadores + y * para hacerlo.
Todos los numerables básicos son concatenables: listas, tuplas,
cadenas de caracteres, bytes y bytearrays.
Los diccionarios son mezclables con el método update() (in situ) y
los conjuntos con los métodos update() (in situ) y union() (copia).

Numerables
Los numerables (sucesiones) se componen de elementos de diferente o
igual tipo, siendo lo distintivo el que sus elementos se pueden
referenciar mediante índices numéricos: 0,1,2,..., comenzando siempre
en 0.
Por ejemplo, si x es un contenedor numerable, sus elementos se
referencian mediante índices entre corchetes: x[0], x[1], x[2], ...
x[n-1]
También se pueden usar índices negativos, donde:
x[-1]=x[n-1]; x[-2]=x[n-2]; … ; x[-k]=x[n-k]; … ; x[-n]=x[0]

Puesto que los elementos de x pueden ser a su vez contenedores en


múltiples niveles, se referencian agregando mas índices entre
corchetes, por ejemplo:
x[i][j]
hace referencia al elemento j, del elemento contenedor i en x

x[i][j][k]...[m]
hace referencia al elemento m en un contenedor de múltiples niveles
en x

Los principales numerables en Python son las listas, las tuplas, las
cadenas de caracteres y los arreglos bytes.
El módulo numpy permite crear arreglos (arrays) que son numerables.

Cadenas de caracteres:
Están compuestas de caractes de letras, números y signos.
Se crean asignándolas entre comillas simples o dobles, mediante la
función str o con una función que devuelva una cadena.
Son numerables, concatenables, pero inmutables, lo que significa que
no se pueden modificar sus elementos.
Los operadores + y * actúan como concatenadores de cadenas.
a="Canuto"
len(a)  6 (cantidad de elementos en a)
a[0]  C
a[5]  o
a[-1]  o
a[-2]  t
a[-6]  C
a[3] = "i"  error, porque se intentó modificar un elemento, pero
las cadenas de caracteres son inmutables
a=str(3/4)  '0.75' --> con str el resultado numérico se convierte
en una cadena
Índices positivos y negativos en a:
C a n u t o C a n u t o
-6 -5 -4 -3 -2 -1 0 1 2 3 4 5

Algunos métodos de objetos cadena de caracteres


Las cadenas de caracteres tienen una gran cantidad de métodos
específicos. Estos son sólo algunos ejemplos:
Sea:
a="los pollitos dicen pío, pío, pío"

Mayúscula el primer caracter:


a.capitalize() Los pollitos dicen pío, pío, pío

Cambia todas las mayúsculas a minúsculas


a.lower() los pollitos dicen pío, pío, pío

Cambia todas las minúsculas a mayúsculas


a.upper() LOS POLLITOS DICEN PÍO, PÍO, PÍO

Cuenta el número de ocurrencias de subcadena


a.count("pío")  3

Obtiene el índice de la primera ocurrencia de subcadena en toda a, o


en una subcadena de a delimitada por índices
a.find("ll")  6
a.find("x")  -1 (si no existe devuelve -1)

Obtiene el índice de la primera ocurrencia de subcadena en toda a, o


en una subcadena de a delimitada por índices. La diferencia con find
es que remite una condición de error si no encuentra la subcadena

a.index("o",6,12)  10 (busca "o" en subcadena de a entre índices 6


y 11 inclusive. Incluye el 6 pero excluye el
12)

Reemplaza las 3 primeras "o" por "a". Si no se especificase el


número, las reemplazaría todas.
a.replace("o","u",3)  lus pullitus dicen pío, pío, pío
a.strip()  elimina espacios en blanco al comienzo y al final de a
a.strip("o")  elimina oes al inicio y final de a
a.rstrip("o")  elimina oes al final de a
a.lstrip("l")  elimina eles al inicio de a
a.lstrip("l").rstrip("n")  elimina eles al inicio y enes al final

¿Está contenido en el contenedor?


"pollitos" in a  True ¿está pollitos en a?
a.__contains__("pollitos") True ¿está pollitos en a?
"gatitos" in a  False
El método join permite utilizar la cadena como pegamento de otras
cadenas. Ejemplo: unir los elementos de una lista mediante espacio en
blanco
" ".join(["perro","gato","raton"]) --> perro gato raton

bytes
Son arreglos inmutables, numerables, concatenables, similares a las
cadenas de caracteres, pero destinados a contener cadenas de bytes,
cuyos valores binarios están entre 0 y 255. Se crean con la función
bytes().
Las cadenas de caracteres sólo contienen caracteres ascii codificados
en binario con valores entre 0 y 127, suficientes para el idioma
Inglés pero insuficientes para los demás idiomas.
Al crear un arreglo bytes hay que especificar la codificación de los
caracteres, que usualmente será "ascii", "latin-1" y "utf-8" en
idiomas latino occidentales.
ascii está limitado a 128 caracteres
latin-1 permite hasta 256 caracteres
utf-8 permite millones de caracteres, porque un carácter puede estar
representado por uno, dos o mas grupos de bytes.
Todas las codificaciones son iguales a ascii en los 128 primeros
caracteres, pero pueden diferir del 129 en adelante.
Ejemplo:

bytes("La piragüa tenía un cañón","latin-1") 


b'La pirag\xfca ten\xeda un ca\xf1\xf3n' (codificación latin-1)

bytes("La piragüa tenía un cañón","utf-8") 


b'La pirag\xc3\xbca ten\xc3\xada un ca\xc3\xb1\xc3\xb3n' (utf-8)

Los caracteres ü, ñ, í, ó no son caracteres ascii.


La codificación de la letra ñ en latin-1 es f1 en hexadecimal, o 241
en decimal. Mientras que su codificación en utf-8 es con una pareja
de bytes: c3 b1 en hexadecimal o 195 177 en decimal. Por lo tanto el
arreglo completo tendrá dos bytes adicionales en utf-8.

Los demás caracteres se codificarán igual que ascii.

Lista de los bytes en números, codificación latin-1:


list(bytes("La piragüa tenía un cañón","latin-1"))

Los métodos de los arreglos bytes son iguales a los de cadenas de


caracteres.

Bytearrays
Son iguales a los arreglos bytes pero mutables.
Se crean con la función bytearray().
Son concatenables con operadores + y * y el operador = produce un
duplicado o alias. Sus elementos son numerables.
Listas:
Se pueden crear especificando sus elementos entre corchetes y
separados por comas, mediante la función list o una función que
devuelva una lista.
Las listas son objetos numerables, concatenables, mutables.
Los operadores + y * actúan como concatenadores de listas.
a = [ 24.5, 45-0.7j, "Garfield", [42,"Pulgoso"]]
a[0]  24.5
a[2]  "Garfield"
a[2][0]  "G"
a[2][5]  e
a[3][1]  "Pulgoso"
a[3][1][3]  "g"
a[-2]  "Garfield"
a[-1][-1][3]  predecir el resultado
b=[37] lista de un solo elemento
a=list((2,3,5))  [2,3,5] creación de lista mediante función list
def fu(x): return(x**3-9) se define una función con nombre fu
a=[fu, lambda x: 3*x+7] lista con fu y una función lambda
a[0](3)  18 evaluando en x=3 la función fu
a[1](10)  37 evaluando en x=10 la función lambda

Las listas son mutables. Esto significa que es posible cambiar el


valor de sus elementos individualmente.
a[3][0] = 21 cambia 42 por 21

Copias y duplicados
Si se hace:
x=[5,3,7,2]
y=x
aquí y no es una copia de x, sinó un duplicado, réplica o alias, lo
que significa que se trata del mismo objeto con dos nombres.
Si ahora se hace:
y[2]=11
Entonces:
x[2]  11
Como se trata del mismo objeto, al modificar uno se modifica el otro.

Los duplicados o réplicas sólo se pueden hacer con objetos mutables


como listas, conjuntos, diccionarios y bytearrays; pero no con
cadenas de caracteres, bytes ni tuplas.

Una forma de verificar si dos objetos mutables son el mismo o


independientes es con el operador is o con la función id.
Por ejemplo, si:
x is y  False
Si el resultado es False, los objetos son independientes y si el
resultado es True son el mismo objeto.
Lo mismo vale con la función id, la cual indica la ubicación en
memoria del objeto:
id(x)==id(y)  False
Si el resultado es False son objetos independientes y si es True son
el mismo objeto.

En el caso de dos objetos inmutables resultado de una copia, la


prueba siempre dará True, ya que por economía comparten la memoria
(porque justamente son inmutables). Pero si uno de ellos se redefine,
la prueba producirá False.

Para hacer una copia independiente de un objeto mutable se puede usar


el método copy. Ejemplo:
y=x.copy()
x is y  False
id(x)==id(y)  False
Ahora la modificación de uno no afecta el otro.

Para determinar la clase de un objeto usar la función type()

Algunos métodos específicos de las listas:


x.sort()  [2,3,5,7] ordena in situ. Significa que el x original
"desordenado" se pierde. Los elementos deben ser todos
del mismo tipo.

x.reverse() [2,7,3,5] voltea la sucesión in situ.

x.append(11)  [2,3,5,7,11] agrega elemento al final de la lista


x.append([11,13])  [2,3,5,7,[11,13]] agrega lista in situ

x.extend(["perro","gato"])  [5,3,7,2,"perro","gato"]
agrega elementos de otra lista in situ

y=x+["perro","gato"]  [5,3,7,2,"perro","gato"]
concatena objetos a la lista, pero no in situ. Es
decir, se preserva el x original

x.remove(x[1])  [5,7,2] saca de la lista in situ el valor indicado

x.insert(2,11)  [5,3,11,7,2] inserta 11 in situ en la posición


índice 2 de la lista

x.insert(100,"perro")  [5,3,7,2,"perro"]
equivale a un append si el índice es igual o mayor
que la cantidad de elementos de la lista
y=x.pop(2)  y  7; x  [5,3,2] extrae in situ el elemento de la
lista indicado por un índice. Es similar al método
remove, pero adicionalmente asigna el elemento
extraido a una variable.

x.index(2)  3 indica el índice de la primera ocurrencia del valor


2 en la lista, o en una sublista comprendida entre
dos índices.

x.count(7)  1 indica la cantidad de ocurrencias del valor 7 en la


lista

Otros métodos:
x.__contains__(2)  True indica si la lista contiene el valor 2.
Debería usarse antes de usar el método index para
evitar error si la lista no contiene el valor.
Opcionalmente se puede utilizar: 2 in x --> True
2 in x  True

Tuplas
Son contenedores numerables, concatenables, pero inmutables.
Se pueden crear especificando sus elementos entre paréntesis y
separados por comas, mediante la función tuple o una función que
devuelva una tupla.
Los operadores + y * son concatenadores de tuplas.
a= 2,  (2,) tupla de un solo elemento
a= 2,3,5,7  (2,3,5,7)
a= tuple((2,3,5,7)) con la función tuple
a=(2,(3+4j),["Canito","Claudio",(54.2,[25,"r"])])
a[2][2][1][1]  "r"
a[2][2][1][1] = p cambia "r" por "p" en una lista en a
a[0]=3  error porque se intentó modificar una tupla
def fu(x): return(x**3-9) se define una función con nombre fu
a=(fu, lambda x: 3*x+7) tupla con fu y una función lambda
a[0](3)  18 evaluando en x=3 la función fu
a[1](10)  37 evaluando en x=10 la función lambda

Métodos para las tuplas


La cantidad de métodos específicos de las tuplas son sólo 2: count e
index
Ejemplo:
a = 2,3,5,7,7
a.count(7)  2 cuenta el número de ocurrencias de 7 en la tupla
a.index(7)  3 obtiene el menor índice del valor 7 en la tupla
5 in a  True
a.__contains__(7)  True

Conjuntos
Son contenedores mutables de elementos inmutables, no indexables. Se
crean especificando sus elementos (sólo inmutables), entre llaves,
separados por comas, mediante la función set, o una función que
devuelva un conjunto.
Al crear un conjunto, los elementos repetidos son reducidos a uno
solo.
Los conjuntos no son concatenables con los operadores + y *

a={5.74,"Benito","Cucho","Demóstenes",(3,5,7)} (creado con llaves)


b=set(("Espanto","Panza",5.74)) (creado con función set)
len(a)  5 (cantidad de elementos en el conjunto)
"Cucho" in a  True (¿está Cucho en a?)
a.add(69) método add, agrega elementos inmutables al conjunto
a.remove(69) método remove, elimina elementos del conjunto

Algunos métodos de conjuntos


Método union, obtiene la unión de dos conjuntos. No se repiten
elementos comunes.
a.union(b)  {5.74, 'Demóstenes', 'Panza', (3, 5, 7), 'Cucho',
'Benito', 'Espanto'}

Método difference, obtiene un conjunto con todos los elementos del


primero, pero excluyendo todos los elementos comunes con el segundo
conjunto. (Primero sin el segundo).
O sea, el conjunto resultante no tiene ningún elemento en común con
el segundo conjunto. Sólo exclusivos del primero.
Si el primero es subconjunto del segundo, el resultado es el conjunto
vacío (pero lo inverso no necesariamente, a menos que sean idénticos)
a.difference(b)  {'Demóstenes', 'Cucho', (3, 5, 7), 'Benito'}
b.difference(a)  {'Espanto', 'Panza'}

Método intersection, obtiene el conjunto de los elementos comunes a


dos conjuntos.
a.intersection(b)  {5.74}
b=a.copy() b es copia de a (b=a sólo crea un duplicado)

Diccionarios
Contenedor mutable en la que los valores (values) se referencian por
claves (keys). Las claves son índices inmutables tales como números
enteros, flotantes, cadenas de caracteres o tuplas.
El indexado es asociativo, pero no numerable (hash).
Los diccionarios no son concatenables con los operadores + y *
Un diccionario se puede formar mediante parejas de clave, valor donde
la clave y su valor se separan con : .
También se puede usar la función dict o una función que devuelva un
diccionario.
Ejemplos:

a={'perro':'Pulgoso','escalar':23.4,'lista':[2,3,5]} (con llaves)


b=dict([("perro",'Canito'),('gato',"Garfield")]) (con función dict)
"perro" in a  True
"Pulgoso" in a  False
a.__contains__("escalar")  True
a.__contains__(23.4)  False
5 in d["lista"]  True
a["perro"]  "Pulgoso" obtiene el valor correspondiente a "perro"
a["perro"]="Canito"  cambia el elemento perro a Canito
a["lista"][1]  3 elemento dentro de valor del diccionario a
b["raton"]="Jerry"  agrega "raton":"Jerry" al diccionario b
Para poder agregar, el diccionario tiene que existir previamente,
aunque esté vacío.

c={"fun1" : lambda x: 3*x+1, "fun2" : lambda x: x**2+12}


c["fun1"](5.2)  16.6
c["fun2"](10)  112
Unir diccionarios
Si a y b son diccionarios, se puede crear un tercer diccionario c
con:
c=dict( list(a.items()) + list(b.items()) )
ó
c=a.copy()
c.update(b)
Si existen claves comunes en a y b, el valor final asociado a las
claves será el del diccionario b, o el del mas a la derecha si son
mas de 2 diccionarios.

Un diccionario se puede construir a partir de una cadena de


caracteres, lista, tupla, bytes o conjunto usando la función dict
junto con la función enumerate.
La función enumerate crea una enumeración cuyos elementos son tuplas
compuestas por una pareja de un entero y otro escalar. En un
diccionario el entero sirvirá como clave, comenzando desde 0
Ejemplos:
list("abc")  ['a', 'b', 'c'] transforma cadena en lista
list(enumerate(list("abc")))  [(0, 'a'), (1, 'b'), (2, 'c')] lista
dict(enumerate(list("abc")))  {0: 'a', 1: 'b', 2: 'c'} diccionario

Los conjuntos y los diccionarios no son numerables, ni concatenables


con los operadores + y * . Sus elementos no tienen un orden
particular dentro del contenedor. Al usar la función enumerate con
ellos, el orden de los elementos será elegido por Python.

Algunos métodos de los diccionarios


b.items()  dict_items([('perro', 'Canito'), ('gato', 'Garfield')])
a.keys()  dict_keys(['perro', 'escalar', 'lista'])
a.values()  dict_values(['Pulgoso', 23.4, [2, 3, 5]])
a.get("perro")  "Pulgoso" obtiene el valor de "perro"
a["perro"]  "Pulgoso" obtiene valor de "perro"
a.get("gallo","Claudio")  "Claudio" (usando valor por omisión)
c=a.copy() c es copia de a (c=a sólo crea un duplicado)
x=a.pop("escalar") saca "escalar" del diccionario y asigna valor a x

Secciones en numerables
Permiten obtener subconjuntos de contenedores numerables. Son
similares a los rangos en Octave.
Están definidos por un trío de números: inicio, final e incremento,
separados por dos puntos (:)
inicio:final:incremento
Los valores predeterminados, si se omiten son:
inicio = 0
final = n-1, donde n es el número de elementos del contenedor
incremento = 1
Cuando el índice final se indica explícitamente, el correspondiente
elemento no se incluye en el subconjunto.
El valor final y el incremento pueden ser negativos.

Ejemplos:
A=[2,3,5,7,11]

A[1]  3
A[:]  [2, 3, 5, 7, 11]
A[::]  [2, 3, 5, 7, 11]
A[:4]  [2, 3, 5, 7] (elemento final 4 es 11, pero no se incluye)
A[:10]  [2, 3, 5, 7, 11]
A[1:]  [3, 5, 7, 11]
A[1:3]  [3, 5]
A[::2]  [2, 5, 11]
A[::-1]  [11, 7, 5, 3, 2]
A[3::-1]  [7, 5, 3, 2]
A[3:0:-1]  [7, 5, 3]
A[3:1:-1]  [7, 5]
A[:-1]  [2, 3, 5, 7] (elemento final -1 es 11, pero no se incluye)
A[:-2]  [2, 3, 5]
A[-2]  [7]
[A[i] for i in (1,3,2)]  [3, 7, 5] (usando comprensión)
Tabla de contenedores y algunas de sus características
Contenedor Mutable o Copia o Elementos Concatenable o
inmutable duplicado con numerables o no concatenable
operador = no numerables con operadores
+ *
lista mutable duplicado numerables concatenable
tupla inmutable copia numerables concatenable
cadena de inmutable copia numerables concatenable
caracteres
conjunto mutable duplicado no numerables no concatenable
pero
elementos
inmutables
diccionario mutable duplicado no numerables no concatenable
bytes inmutable copia numerables concatenable
bytearray mutable duplicado numerables concatenable
Instrucciones de Python

Rangos
Igual que en Octave, los rangos consistentes en un trío de números
que definen un valor inicial, un incremento y un valor tope.
Los rangos básicos de Python son sólo con números enteros.
Sin embargo, es posible utilizar rangos con punto flotante usando el
módulo Numpy.
La principal utilidad de los rangos es para iterar.

Ejemplos:
list(range(3))  [0,1,2] (inicio=0, incremento=1, tope=3)
tuple(range(3,7))  (3,4,5,6) (inicio=3, incremento=1, tope=7)
tuple(range(3,11,2))  (3,5,7,9) (inicio=3, incremento=2, tope=11)
list(range(15,6,-3))  [15,12,9] (inicio=15, incremento=-3, tope=6)
list(range(8,2))  [] (vacía) (inicio=8, incremento=1, tope=2)
tuple(range(5,5))  () (vacía) (inicio=5, incremento=1, tope=5)

En estos ejemplos se usó la instrucción range para crear listas o


tuplas.
Si no se especifican, entonces implícitamente el valor inicial del
rango es 0 y el incremento es 1
Notar que el rango siempre incluye el valor inicial pero nunca
incluye el valor tope.
Si el valor tope es menor o igual que el valor inicial, el rango no
contiene ningún elemento.

Condicionales if
Ejemplo:
dice="miau"
if dice=="guau":
print("bicho= perro")
elif dice=="miau":
print("bicho= gato")
else:
print("bicho= gallo")

(en el shell Ipython o IDLE terminar el bloque de instrucciones con


dos enter seguidos)

Notar que las líneas con if, elif y else terminan obligatoriamente
con : .
elif equivale a else if ó elseif de otros lenguajes.
Igual que en otros lenguajes, las instrucciones elif y else son
opcionales.
El sangrado de las instrucciones dentro del bloqe if es obligatorio
en Python. El sangrado debe ser de 1 o mas espacios (pero todos
iguales dentro del mismo bloque).
Es permitido poner una o varias instrucciones en una misma línea
separadas por ; siempre que no se tenga mas de una instrucción que
requiera sangrado como if, elif, else, for, while

Ejemplo:
dice="miau"; perro="Canuto"; gato="Garfield"; gallo="Claudio"
if dice=="guau": print("bicho= perro"); print(perro)
elif dice=="miau": print("bicho= gato"); print(gato)
else: print("bicho= gallo"); print(gallo)

Condicional en una instrucción


Cuando se tiene un condicional con exactamente if y else y una sola
instrucción en cada una, por ejemplo:
if dice=="guau" # condicción - instrucción
print("bicho= perro")
else:
print("bicho= gato")

se puede intercambiar por instrucción - condición :


print("bicho= perro") if dice=="guau" else print("bicho= gato")

Con este tipo de condicionales sólo se puede realizar una asignación,


en la forma:
variable = ( operación_1 if condicion else operación_2 )

Ejemplo: multiplicar por 2 un número entero x si es impar y dividirlo


entre 2 si es par:

y = ( x*2 if x%2 else int(x/2) )

Ciclos for
Ejemplos:
for x in 2,3,5,7: #(notar los : obligatorios al final)
y=x*2-1 #(sangría obligatoria de uno o mas espacios)
print(y)

(en el shell Ipython terminar el bloque de instrucciones con dos


enter seguidos)

imprime 2,3,5,7 en columna

for x in "los pollitos dicen":


x=x.upper()
print(x)

imprime "LOS POLLITOS DICEN" en columna


for k in dict([("perro","guau"),("gato","miau")]).values():
print(k)

Imprime:
guau
miau

for k in range(3,9,2):
print(k)

Imprime 3,5,7 en columna. No imprime 9 porque range(3,9,2) no incluye


el valor tope 9.

Doble ciclo for:


for k in range(1,10):
for n in range(k,10):
print(k*n)

Imprime todos los productos k*n con k y n entre 1 y 9.


No repite productos conmutativos porque el segundo for comienza en k

La instrucción for debe terminar obligatoriamente con :


Las instrucciones dentro del ciclo for deben tener obligatoriamente
una sangría de al menos 1 espacio respecto al for. Lo tradicional es
de 4 espacios. Todas las sangrías deben ser iguales.
El ciclo for no tiene una instrucción de terminación, tal como end en
Octave o done en Bash. Tampoco existe llave de apertura y cierre como
en C. En Python se termina el ciclo for regresando la sangría al
mismo nivel que la instrucción for que lo inició.
En el shell Ipython o IDLE se termina con dos enter seguidos.

Instrucción continue
Se utiliza para terminar una iteración en ciclos for o while. No
termina el ciclo for, sinó sólo la iteración actual.

Ejemplo
Imprime el cuadrado de los números pares.

for k in range(1,10):
if k%2: continue
print("k*k= ",k*k)

Cuando k es impar (k%2==1) el if k%2 produce True y por lo tanto


ejecuta la instrucción continue. Ésta termina esa iteración y vuelve
al comienzo del ciclo con el siguiente valor de k.
El resultado es que sólo se ejecuta la instrucción print cuando k es
par.
Instrucción break
Se utiliza para terminar un ciclo for o while

Ejemplo
Imprime el cuadrado de los números impares menores que 13.

for k in range(100):
if k==13: break # termina ciclo for si k==13
if k%2-1: continue # termina iteración actual si k es par
print("k*k= ",k*k)

For en una lista implícita por comprensión (comprehension)


Ejemplo
Obtener la raiz cuadrada de los elementos de una lista. El resultado
es otra lista de iguales dimensiones.

x=[2,3,5,7]
[pow(x[k],0.5) for k in range(len(x))]
 [1.4142135623730951, 1.7320508075688772, 2.23606797749979,
2.6457513110645907]
len(x) es una función que indica la cantidad de elementos en la lista
x. En general, la función len() indica la cantidad de elementos en un
contenedor tales como cadenas de caracteres, listas, tuplas,
conjuntos y diccionarios.

El mismo ejemplo con for y un condicional if


x=[2,3,5,7]
[pow(x[k],0.5) for k in range(len(x)) if k!=2 ]
 [1.4142135623730951, 1.7320508075688772, 2.6457513110645907]

Ejemplo
Obtener el cuadrado de cada elemento de una lista de listas. El
resultado es otra lista de listas con la misma estructura.

A=[[2,3,5],[7],[11,13]]
[[(A[i][j])**2 for j in range(len(A[i]))] for i in range(len(A))]
 [[4, 9, 25], [49], [121, 169]]

Aquí hay dos ciclos for. El mas interno con la variable j se mueve
por las "columnas" y donde len(A[i]) indica la cantidad de columnas
en la "fila" i-esima.
La variable i mueve las "filas" y len(A) indica la cantidad de filas
en la lista A.

Instrucción else con for


En Python se permite utilizar una instrucción else a continuación de
un ciclo for. La utilidad es determinar si se completó el ciclo for.
Ejemplo
Encontrar tríos de Pitágoras a*a+b*b=c*c, a, b, c enteros,
a<10, b<100

Este ejemplo es sólo para propósitos demostrativos de else.


Para un a dado pueden existir múltiples b que conformen un trío, pero
en este algoritmo se toma sólo el trío del menor b que encuentre.

for a in range(2,10):
for b in range(a+1,100):
c=(a*a+b*b)**0.5
if int(c)==c:
print("Trío de Pitágoras: ",a,b,int(c))
break
else:
print("No hay trío con a= ",a)

No hay trío con a= 2


Trío de Pitágoras: 3 4 5
No hay trío con a= 4
Trío de Pitágoras: 5 12 13
Trío de Pitágoras: 6 8 10
Trío de Pitágoras: 7 24 25
Trío de Pitágoras: 8 15 17
Trío de Pitágoras: 9 12 15

Instrucción while
Ejemplo
Se trata del método de Newton tratando de encontrar
una raiz real que no existe: y = x**2+1 = 0
Es un ejemplo sólo para ilustrar la instrucción while,
no realiza ningún cálculo útil.

k=1 # iteración inicial


x=2 # x inicial
while abs(x)<4: # condición de terminación
x=((-x+2)*x-1)/(2*x) # calcula siguiente x
if k>99:break # terminar por exceso de iteraciones
k+=1 # incrementa contador de iteraciones
print(k,x) # imprime iteración y x
else:
print("Terminación normal sin break")

La condición de terminación también se pudo escribir como:


while abs(x)<4 and k<100:
y quitar el if k>99:break
O bien usar:
while True:
---------
if abs(x)>=4 or k>99: break

El bloque de la instrucción else se ejecuta sólo si el bloque while


termina porque la condición lógica del while es False (terminación
normal).

Operadores lógicos

True and False  False


True or False  True
True & False  False (and)
True | False  True (or)
not True  False (negación)

Los escalares lógicos pueden resultar de operadores de comparación o


del resultado de funciones.
Además escalares numéricos enteros o flotantes iguales a cero
equivalen a False lógico. Cualquier otro valor equivale a True

not 5  False
not 0  True
5 > 2  True
not 5 > 2  False (se traduce en: 0 > 2  False)
5 > (not 2)  True (se traduce en: 5 > 0  True)

Comprensiones (comprehensions) y generadores

Son el análogo en Python de la definición en Matemática de un


conjunto particular por comprensión o forma implícita.
Lo contrario es definición por extensión o explícita, donde se
enumeran todos los elementos del conjunto. Obviamente sólo
los conjuntos con una cantidad finita y relativamente pequeña de
elementos se definen por extensión.
La utilidad de las comprensiones suele ser:
- crear fácilmente sucesiones de escalares en un contenedor
utilizando alguna función. Esto es ideal para crear series numéricas
finitas.
- aplicar una función a cada elemento de un contenedor preexistente o
sucesión. La alternativa a esto es usar las funciones del módulo
numpy.

Ejemplos de Matemática:
Conjunto definido por extensión:
𝐴 = { 2, 3, 5, 7 } (números primos menores que 10)

Conjunto definido por comprensión:

𝐵 = { |𝑥|, 𝑥 ∈ 𝑍, |𝑥| < 10 } (los números enteros entre –10 y 10)

El análogo en Python puede ser una lista, una tupla, un conjunto o


una sucesión, creada con range.
Por ejemplo, el conjunto A en una lista por extensión:
A=[2,3,5,7]

El conjunto B por comprensión:


B=[abs(x) for x in range(-9,10)] (lista)
B=tuple(abs(x) for x in range(-9,10)) (tupla)
B={abs(x) for x in range(-9,10)} (conjunto)
B=(abs(x) for x in range(-9,10)) (generador)

Observaciones:
- La lista y el conjunto pueden ser creados usando corchetes y llaves
o las funciones list y set respectivamente, pero la tupla tiene que
ser creada con la función tuple; sinó sólo crea una clase de objeto
denominado "generator" o generador.
Los generadores no contienen valores, sinó sólo la receta para
crearlos y ponerlos en un contenedor como una lista, tupla o
conjunto. También para usarlo en ciclos for.
La ventaja del generador es que no ocupa memoria RAM con los valores
hasta que eventualmente sean necesarios.
Los generadores sólo se pueden usar una vez. A la segunda o mas veces
sólo producirá conjuntos vacíos.
Por ejemplo, si B es un generador:
C=list(B) producirá una lista

- En la lista y la tupla los valores de x están repetidos dos veces


entre 1 y 9 debido al valor absoluto, pero en el conjunto (set) sólo
se tienen valores entre 0 y 9, porque los conjuntos en Python no
tienen valores repetidos.

- Las comprensiones equivalen a una combinación de la acción de las


funciones map y filter

Ejemplo con condicional:


El mismo conjunto de enteros pero sólo los impares:
B=[abs(x) for x in range(-9,10) if x%2 ]

Ejercício:
Obtener una tupla con los números enteros múltiplos de 3 comprendidos
entre 0 y 50
Ejemplo con dos variables y condicional:
C=[(x*x+y*y)**0.5 for x in [2,4,6,8] for y in [1,3,5,7,9] if abs(x-
y)<3]

El doble for produce 4*5=20 combinaciones de x con y, pero el cálculo


se limita a los que la diferencia entre x,y es menor que 3
La y se mueve mas rápido, o sea, se procesan los pares en el orden:
2,1 2,3 2,5 2,7 2,9 4,1 4,3 …

Tarea
Calcular la aproximación de arctan(x) con 10 términos de la serie de Taylor
para x=0.ijk, donde ijk son los 3 últimos dígitos de su cédula. La serie se
obtiene con una comprensión y después se usa la función sum para sumar los
términos.

𝑥3 𝑥5 𝑥7
𝑎𝑟𝑐𝑡𝑎𝑛(𝑥) = 𝑥 − + − + ⋯ , −1 ≤ 𝑥 ≤ 1
3 5 7

(el resultado está en radianes)

Funciones lambda
Son el equivalente de las funciones inline en Octave.
Consiste en una función definida con una sola instrucción.
Ejemplo:
f=lambda x,y: 3*x + 2*y (x,y representan los argumentos)
f(1,2)  7 (x=1, y=2)
f(y=3,x=0)  6

Se suele utilizar para generar directamente argumentos de otras


funciones.

Función map
Su utilidad es aplicar una función a cada elemento de uno o varios
contenedores para obtener otro contenedor con el resultado. Equivale
a vectorizar funciones aplicadas a contenedores.

Su forma genérica es:


map(función,contenedores)
Aquí los contenedores contienen los argumentos de la función en orden
de izquierda a derecha y produce como resultado un mapa, el cual se
puede verter en otro contenedor.

Ejemplo.
Obtener una lista con los cuadrados de los elementos de la lista A
A=[2,3,5,7]
Problema: puesto que A es una lista, no es válido hacer pow(A,2),
porque las funciones normales de Python no están vectorizadas.

Pero usando una función map:


f = lambda x: pow(x,2)
list( map(f,A) )  [4, 9, 25, 49]

O bién:
C = map( lambda x: pow(x,2), A )
for i in C: print(i)  4,9,25,49

En este ejemplo se tuvo que usar una función lambda porque pow
requiere dos argumentos.
Si el problema fuese obtener el valor absoluto de los elementos de la
lista sería suficiente con:
list( map(abs,A) )
Implícitamente abs tomaría como argumento los elementos de A uno a
uno.

Ejemplos map con dos contenedores con igual cantidad de elementos

A=[2,3,5,7]
B=[11,13,17,19]
C=map( lambda x,y: x*y, A,B )
list(C)  [22, 39, 85, 133]

list(map(pow, A, len(A)*[2])) # pow es función de 2 argumentos


 [4, 9, 25, 49]

Ejemplo map con función de 3 argumentos:

def f(x,y,z):
return(x+y-z)
x=[1,2,3]; y=[4,5,6]; z=[7,8,9]
list(map(f,x,y,z))  [-2, -1, 0]

Tareas
Definir la función signo y aplicarla a los elementos de un contenedor para
obtener el resultado en una lista.
Por ejemplo: list( map(signo, [-5.7, 3.21, 0.0]) )  [-1, 1, 0]

Obtener el producto escalar ordinario de dos listas numéricas usando la


función map y la función sum.
Por ejemplo, el producto escalar de [1,2,3,4] con [5,-6,7,-8] es -18

Para funciones muy complejas o con varios argumentos, si no es


posible usar una función lambda entonces se puede usar una función
definida por el usuario.
También una comprensión pueden ser una mejor alternativa que map.
La función map produce un mapa, el cual es análogo a un generador,
por ello se usó la función list para concretar el mapa en una lista.
Al igual que los generadores los mapas se pueden usar sólo una vez
para crear una lista, tupla o conjunto o elemento a elemento en
ciclos for.

Función filter
Su utilidad es seleccionar elementos de un contenedor en base a una
función que produce resultados lógicos True o False. Con filter no se
calcula nada: la función sólo se utiliza para evaluar cada elemento
del contenedor, y se toman sólo aquellos elementos para los cuales la
función lógica produce True. Por lo tanto, el resultado estará
constituido por un subconjunto del contenedor original. Como casos
particulares, puede ser vacío o igual al original.

Forma genérica:
filter(función lógica, contenedor)

La función lógica se aplica a cada uno de los elementos del


contenedor.
El resultado es un objeto clase filtro sobre el contenedor, que se
puede verter en otro contenedor, de forma similar a los generadores y
mapas.

Ejemplo, seleccionar los números pares de una lista:

pares= lambda x: not x%2


C=filter( pares, [1,2,3,4,5,6] )
list(C)  [2,4,6]

en el ejemplo la función lambda


"pares" produce resultados True o False según el valor en la lista
sea par o impar. El filtro toma sólo los que corresponden con True
(los pares).

Para funciones mas complicadas se puede usar una función definida por
el usuario en lugar de una lambda.

Las comprensiones, mapas y filtros, resultan particularmente útiles


cuando los elementos del contenedor al cual se aplican son todos del
mismo tipo.
Funciones internas de Python

Las funciones internas son aquellas que no requieren ser importadas


de un módulo. En la versión 3.4 de Python son las indicadas en la
siguiente tabla

Funciones internas de Python 3.4


abs() dict() help() min() setattr()
all() dir() hex() next() slice()
any() divmod() id() object() sorted()
ascii() enumerate() input() oct() staticmethod()
bin() eval() int() open() str()
bool() exec() isinstance() ord() sum()
bytearray() filter() issubclass() pow() super()
bytes() float() iter() print() tuple()
callable() format() len() property() type()
chr() frozenset() list() range() vars()
classmethod() getattr() locals() repr() zip()
compile() globals() map() reversed() __import__()
complex() hasattr() max() round()
delattr() hash() memoryview() set()

https://docs.python.org/3/library/functions.html

Funciones matemáticas

abs
Obtiene la magnitud de un escalar, sea real o complejo
abs(-3.7)  3.7
abs(-1.2+1.6j)  2.0

pow
Eleva un número a una potencia. Opcionalmente obtiene un residuo.
Para obtener residuo todos los argumentos deben ser enteros, y el
segundo debe además ser positivo.

pow(49,0.5)  7.0
pow(7,2,5)  4

complex
Devuelve un número complejo dados dos números o una cadena
convertible.
complex(7)  (7+0j)
complex(0,1)  1j
complex(5.12, 32.9)  (5.12+32.9j)
complex(3+4j,5+6j)  (-3+9j) = 3+4j + j*(5+6j)
complex("11+7j")  (11+7j) (la cadena no debe tener espacios)

divmod
Devuelve una tupla con el cociente y el residuo dados el dividendo y
el divisor. El cociente es siempre un número sin decimales. El
residuo puede tener decimales.
Los argumentos no pueden ser números complejos.
divmod(23.5,8.5)  (2.0,6.5)

max
Devuelve el mayor elemento en un contenedor o el mayor de los
argumentos.
Si son caracteres, toma el que tenga mayor código ascii.
Los argumentos no pueden ser números complejos.
max("Los pollitos dicen")  't'
max("a","A")  'a'
max([34,12,6,69]  69

min
Devuelve el menor elemento en un contenedor o el menor de los
argumentos.
Si son caracteres, toma el que tenga menor código ascii.
Los argumentos no pueden ser números complejos.
min("Los pollitos dicen")  ' ' (espacio en blanco)
min("a","A")  'A'
min([34,12,6,69]  6

round
Redondea un número a una cantidad especificada de decimales. Si no se
especifican, redondea a cero decimales.
round(7.6841, 2)  7.68

A=[-3.5, -2.9, -2.5, -2.1, 2.1, 2.5, 2.9, 3.5]


list( map(round, A) )
[-4, -3, -2, -2, 2, 2, 3, 4]
El redondeo es al entero mas cercano, pero cuando está a mitad exacta
entre dos enteros, redondea al entero par. Notar que 3.5 redondea a
4.0, pero 2.5 redondea a 2.0

sum
Sumatoria de elementos de un contenedor de sólo números, puede tener
valor inicial, sinó supone cero.
sum([3,2],4)  9 # valor inicial = 4
sum([2,3,5,7])  17
patas={"gallina":2,"perro":4,"mosca":6,"araña":8} # diccionario
sum(patas.values())  20
Funciones de conversión
ascii
Devuelve la representación en caracteres ascii de un objeto. Genera
un objeto str. Sólo alfanuméricos (letras, números, signos).
ascii(24.7)  '24.7'
ascii([2,3,5,7])  '[2,3,5,7]'
ascii(abs)  '<built-in function abs>'

repr
Devuelve la representación en caracteres ascii de un objeto. Equivale
a la función ascii. Tienen los mismos métodos.

str
Devuelve un objeto arreglo de bytes inmutable de los caracteres de un
objeto. Se puede especificar la codificación. Incluye caracteres de
control y código desde 0 hasta 255.
Si no se especifica, utiliza utf-8 para codificar y decodificar.
("ascii", "latin-1", "utf-8")
a=str(3.6).encode("latin-1")  b'3.6'
a=str.encode("Cañón")  b'Ca\xc3\xb1\xc3\xb3n' (utf-8 predet.)
a=str.encode("Cañón","latin-1")  b'Ca\xf1\xf3n'
b=a.decode("latin-1")  Cañón

El método decode se puede utilizar con objetos bytes o bytearray,


para mostrar el texto sin los caracteres indicadores de codificación,
pero se debe decodificar exactamente con el mismo código con que fue
codificado.

bytes
Similar a str, pero siempre se debe especificar la codificación.
Difiere en algunos métodos con str. Enteros entre 0 y 255.

Un entero se puede convertir a un arreglo de bytes con el método


.to_bytes:
n=-2069
m = n.to_bytes(2,byteorder="big",signed=True)  m = b'\xf7\xeb'
Se especifican el número de bytes para representar el entero, el
orden de bytes y si es entero con signo o sin signo

El método inverso es .from_bytes:


n = int.from_bytes(m,byteorder="big",signed=True)  n = -2069

bytearray
Similar a bytes, pero produce un objeto arreglo de bytes mutable.

bin
Convierte un entero a una cadena de caracteres de la representación
binaria, con prefijo "0b"
bin(69)  '0b1000101'
oct
Convierte un entero a una cadena de caracteres de la representación
octal, con prefijo "0o"
oct(69)  '0o105'

hex
Convierte un entero a una cadena de caracteres de la representación
binaria con prefijo "0x"
hex(69)  '0x45'

chr
Devuelve el caracter correspondiente a un entero en el código Unicode
chr(69)  'E'

ord
Devuelve el entero del código Unicode correspondiente a un caracter
ord("E")  69

float
Devuelve un número en punto flotante
float(69)  69.0
float("69.69")  69.69
float("250e-3")  0.25

int
Devuelve un número entero. Se puede especificar una base.
Si el argumento es un número con decimales, trunca los decimales.
int(5.98)  5
int("45",16)  69 # 45 base 16 a decimal
int("0x45",16)  69
int("5.98")  error
int("0x45")  error

bool
Devuelve un escalar lógico True o False.
Todas las cadenas convierten a True excepto la cadena vacía.
Todos los valores numéricos convierten a True excepto el cero entero,
flotante o complejo
bool("Los pollitos dicen")  True
bool("")  False
bool("0")  True
bool(5)  True
bool(0)  False
bool(0.0)  False
Funciones lógicas
all
Retorna True si todos los elementos de un iterable son True o si el
iterable está vacío. En los diccionarios comprueba sólo las claves.
all("Los pollitos dicen")  True
all("")  True
all([2,3,5,7])  True
all([2,3,0,5,7])  False

any
Retorna True si al menos un elemento de un iterable es True.
Si el iterable está vacío retorna False. En los diccionarios
comprueba sólo las claves.
any("Los pollitos dicen")  True
any("")  False
any([0,0,0,0,0])  False
any([2,3,0,5,7])  True

Funciones diversas

dir
Sin argumentos retorna una lista de objetos en el ambiente actual
for x in dir(): print(x)

Con un argumento objeto, lista los atributos y métodos del mismo

Puede usarse para obtener una lista de los métodos y atributos de un


módulo:
import math
for x in dir(math): print(x)

eval
Evalúa una cadena con una sola instrucción Python
eval("round(3.3)")  3

exec
Ejecuta cualquier cantidad de instrucciones Python, las cuales pueden
estar en una cadena de texto, en un archivo, o en código compilado en
bytecodes. Esto permite, por ejemplo, ejecutar programas creados al
instante por otro programa.
programa="for i in range(4):\n print(i*i)" (instrucciones en texto)
exec(programa)  0 1 4 9 (salida en columna)

help
Presenta ayuda sobre un objeto. Es para usarse de forma interactiva
en un shell de Python
help(list)  ayuda sobre list

id
Regresa un número correspondiente a una dirección en memoria de un
objeto. Dos objetos que tengan el mismo id son el mismo objeto.

input
Asigna un valor a una variable de forma interactiva, igual que
Octave, pero el valor asignado es siempre una cadena.
muna=input("Papá dame real <== ") 
Papá dame real <== 100
muna  100 (cadena de texto)

Lo mismo, convertido directamente a flotante:


muna=float(input("Papá dame real <== "))

print
Impresión con formato.
El separador predeterminado es espacio en blanco y el terminador de
línea avance de línea:

x, y = 5, 4.2
print(x,y,"perro")  5 4.2 perro
print(x,y,"perro",sep=" – ")  5 - 4.2 – perro

En el siguiente ejemplo el cursor se queda detenido un espacio


después de perro y después imprime "guau" en la misma línea:

print(x,y,"perro",sep=":",end=" "); print("guau")  5:4.2:perro guau

Se puede utilizar una sintaxis similar a la de Octave, Matlab, C para


formatear la impresión, pero Python ofrece adicionalmente el método
format de los objetos cadenas de caracteres, el cual produce otra
cadena. Además de servir para imprimir resultados formateados,
también se puede usar para componer el texto del título o etiquetas
de un gráfico.

cadena="Aguacates= {} Peso= {} Mascota= {}".format(x,y,"perro")


print(cadena)
 Aguacates= 5 Peso= 4.2 Mascota= perro

print("Aguacates= {2} Peso= {0} Mascota= {1}".format(y,"perro",x))


 Aguacates= 5 Peso= 4.2 Mascota= perro

print("Aguacates= {2:2d} Peso= {0:6.3f} Mascota=


{1}".format(y,"perro",x))
 Aguacates= 5 Peso= 4.200 Mascota= perro
print("Aguacates= {2:03d} Peso= {0:06.3f} Mascota=
{1}".format(y,"perro",x))
 Aguacates= 005 Peso= 04.200 Mascota= perro

Con variables etiquetadas:


print("Aguacates= {fruta:03d} Peso= {kilos:06.3f} Mascota=
{bicho}".format(fruta=x,bicho="perro",kilos=y))
 Aguacates= 005 Peso= 04.200 Mascota= perro

Existen mas opciones para el control del formato:


http://www.python-course.eu/python3_formatted_output.php

open
Función para lectura y escritura de archivos, de texto o binarios
Crea un objeto file, el cual tiene métodos para leer, escribir,
posicionar puntero de lectura/escritura, cerrar el archivo, etc.
El objeto creado es un iterador.
open tiene un argumento obligatorio y muchos opcionales.
El argumento obligatorio es el nombre del archivo a abrir
(preexistente o nuevo)
Entre los argumentos opcionales los mas usados son el modo y la
codificación de los archivos de texto.

Ejemplos:
Abrir bichos.txt . Predeterminados: texto y solo lectura.
Opcional: codificación utf-8 del texto.
ida es el identificador del objeto file:

ida=open("bichos.txt",encoding="utf-8")

Abrir bichos.txt para sólo escritura, modo texto. Si el archivo ya


existe, lo inicializa como vacío:

ida=open("bichos.txt",mode="w")

Abrir bichos.txt para sólo escritura en modo binario:

ida=open("bichos.txt",mode="wb")

Tabla de modos:
'r' sólo lectura (predeterminado). El archivo debe existir.
Puntero al inicio del archivo.
'w' sólo escritura, inicializa el archivo como vacío.
'a' sólo escritura, agregando al final del archivo. Si no
existe lo crea. Puntero al final del archivo.
'x' crea el archivo para escritura, sólo si no existe.
'r+' abre para lectura y escritura. El archivo debe existir.
Puntero al inicio del archivo.
'w+' abre para lectura y escritura. Inicializa el archivo como
vacío.
'a+' abre para lectura y escritura al final del archivo. Si no
existe lo crea. Se puede leer en cualquier posición, pero
en la escritura siempre agrega al final del archivo.
Puntero al inicio del archivo en posición de lectura.
'x+' abre para lectura y escritura. Crea el archivo sólo si no
existe.

'b' modo binario


't' modo texto (predeterminado)

Los modos r,w,a,x,r+,w+,a+,x+ se combinan con los modos b,t

En modo texto, tanto la lectura como escritura al archivo es


únicamente como cadenas de texto. Por lo tanto, escalares enteros,
flotantes, complejos y lógicos deben ser convertidos a cadenas de
texto antes de ser escritos, y el proceso inverso al ser leidos.
Las cadenas de texto son codificadas/decodificadas según se
especifique en los argumentos de la función open.

El modo binario es esencialmente igual al modo texto, pero la


codificación de caracteres debe ser hecha con otra función. No se
especifica la codificación en la función open.
Tampoco entiende de separadores de líneas, por lo tanto hay que
especificar cuantos bytes se leen de cada vez. Si no se especifican
los bytes a leer intenta leer todo el archivo en memoria RAM.

Al final todo se reduce a escribir y leer bytes. La diferencia está


en como se interpretan.

Ejemplo con archivo de texto: EjemploEscrituraArchivoTexto.py


Escribe una columna de formaciones y otra de velocidades sísmicas
El punto mas importante a recordar es que todos los datos deben ser
transformados a texto antes de escribirlos. El texto puede ser unido
en una cadena la cual se escribe una por línea para mayor claridad.

formacion = ["San Juan", "Caratas ", "Vidoño ", "Guárico "]


velocidad = [1200, 1350, 2100, 2200]

ida = open("velocidades.txt", mode = "wt", encoding = "utf-8")

for i in range(len(formacion)):
linea = " ".join((formacion[i], str(velocidad[i])))
ida.write( linea + "\n" )

ida.close()
Se definen dos listas, una con nombres de formaciones geológicas y
otra con velocidades sísmicas.

En la de formaciones geológicas hay un carácter ñ y un acento.


Se abre un archivo para escritura en modo texto, y codificación de
caracteres utf-8. Si existiese un archivo con ese nombre, su
información original se perdería.

No sirve codificación ascii porque no contempla ñ ni acentos.


Las codificaciones alternativas son utf-8 y latin-1 o cp1252

Dentro de un ciclo for se escribe una línea en cada iteración.


Cada línea escrita es una sola cadena de texto.
Sin embargo, esto no es obligatorio: lo que finalmente determina una
línea es el separador de líneas (generalmente "\n").

Los componentes en la línea se juntan con el método join de un par de


caracteres en blanco. Estos caracteres son el separador entre el
nombre de la formación y la velocidad.

Las cadenas de caracteres que debe unir join se proporcionan en una


lista o una tupla; en este ejemplo en una tupla.

El método join no es indispensable. Se pudo haber utilizado cuatro


write por línea: el nombre de la formación, un separador, la
velocidad y el fin de línea.
También se pudieron concatenar en una sola cadena utilizando el
operador +:
ida.write( formacion[i] + " " + str(velocidad[i]) + "\n" )

Todo debe ser texto, por eso la velocidad se convierte a texto con la
función str.

Al momento de escribir la cadena se le concatena al final un avance


de línea. Esto también se pudo haber hecho en el join, o en un write
aparte.

El método write sólo acepta como argumento una cadena de texto. Pero
el método writelines acepta también un contenedor con cadenas de
texto. Sin embargo, queda a cargo del programador agregar separadores
y fin de línea.

La tarea de convertir a texto y concatenar las variables a escribir


queda a cargo del programador. Igualmente al leer debe hacer la
operación inversa: separar variables y convertir a entero, flotante,
complejo o lógico.

Ejemplo de lectura archivo de texto: EjemploLecturaArchivoTexto.py


formacion = [] # inicializa contenedores mutables, vacíos, para
velocidad = [] # agregar una cantidad indefinida de elementos
# Otra forma: formacion=list(); velocidad=list()

ida = open("velocidades.txt", mode = "rt", encoding = "utf-8")

for linea in ida:


formacion.append(linea[0:8])
velocidad.append(float(linea[9:]))
ida.close()

El programador debe saber de antemano como es la distribución de los


datos en el archivo para poder hacer la separación y conversión de
cadenas de texto a enteros, flotantes, complejos y lógicos.
Notar que en este ejemplo no se utilizó un método "read" y que el
archivo se interpreta como un contenedor donde cada línea es un
elemento. Por eso es válida la instrucción: "for linea in ida:"

ida.close() cierra el archivo.

Forma alternativa de lectura o escritura recomendada:

formacion = list(); velocidad = list()

with open("velocidades.txt", mode = "rt", encoding = "utf-8") as ida:


for linea in ida:
formacion.append(linea[0:8])
velocidad.append(float(linea[9:]))

La instrucción with se encarga del cierre de archivo y salida limpia


en caso de error de lectura.

Otras instrucciones:
ida.readline() lee una línea de cada vez
ida.readline(n) lee n bytes
ida.readlines() lee todo el archivo de texto a una lista 2D. Ideal
para archivos con datos en columnas. Se debe
disponer de suficiente memoria RAM libre para
almacenarlo.
ida.read() lee todo el archivo como una cadena de texto en modo
texto o una cadena de bytes en modo binario. Se debe
tener suficiente memoria RAM libre para almacenarlo.
ida.read(n) lee n caracteres en modo texto o n bytes en modo
binario.

Ejemplo:
datosgravedad=open("CG5.txt","r").readlines()
datosgravedad será una lista 2D que contiene una línea de archivo por
fila, todo en texto sin separar en campos.
La separación se puede hacer con los métodos de cadenas strip()
seguido de split(). Después las cadenas separadas se pueden convertir
a flotantes con float() y enteros con int(). Todo con comprensiones o
con map si todos son del mismo tipo.

Ejemplo de escritura y lectura con archivo binario:


EjemploEscrituraLecturaArchivoBinario.py

# Escritura en archivo binario

import struct # importa el módulo de funciones struct

formacion = ["San Juan", "Caratas ", "Vidoño ", "Guárico "]


velocidad = [1200, 1350, 2100, 2200]

ida = open("velocidades.bin", mode = "wb")

for i in range(len(formacion)):
formab=bytes(formacion[i],encoding="utf-8")
paquete = struct.pack("8sd",formab,velocidad[i])
ida.write(paquete)
ida.close()

#----------------------------------------------------------
# Lectura de archivo binario
form=[]
vel=[]

with open("velocidades.bin", mode = "rb") as ida:


while True:
paquete=ida.read(16)
if not paquete: break
datos=struct.unpack("8sd",paquete)
form.append(datos[0].decode("utf-8"))
vel.append(datos[1])

Para mayor eficiencia de almacenamiento y tiempo de procesamiento es


conveniente codificar los escalares enteros, punto flotante y lógicos
a binario en lugar de cadenas de caracteres representando los dígitos
decimales.
El convertir enteros o flotantes a cadenas con str no es eficiente en
almacenamiento. Por ejemplo, el número 3.151592653589793 tiene 17
caracteres y por lo tanto ocupa 17 bytes. El mismo número
representado en binario ocuparía 8 bytes.
Los números enteros pueden ser convertidos a arreglos de bytes con el
método .to_bytes y devueltos a enteros con .from_bytes.
En estos dos métodos hay que especificar todo para la conversión:
número de bytes, orden de bytes y si es entero con signo o sin signo.
(-4269).to_bytes(2,"little",signed=True)  b'S\xef'
Sin embargo, no hay un método equivalente para convertir flotantes a
cadenas de bytes.
Para ello es necesario importar desde el módulo struct funciones que
hacen la conversión de entero o flotante a binario:
import struct
Se tiene una lista con las formaciones y otra con las velocidades.
En el nombre de las formaciones todas tienen 8 caracteres, utilizando
espacios en blanco si es necesario para completar.

Se abre un archivo para escritura, donde "wb" significa abrir en modo


escritura y binario.

Las cadenas de caracteres tienen que ser primero codificadas, sea con
la función str, con la función bytes o con el método encode de
cadenas.
En este ejemplo se utiliza la función bytes para codificar a utf-8.
El resultado se guarda en la variable formab.

Después se utiliza la función struct.pack para empaquetar en una


estructura C, en binario el nombre de la formación y la velocidad.
En el argumento "8sd", 8s indica que se empaquetará un arreglo de 8
bytes; d indica que a continuación se empaquetará un escalar punto
flotante de 8 bytes (no usar flotantes de 4 bytes: se obtiene basura
al desempaquetarlos)

El formato para otros tipos de escalares se puede consultar en:


https://docs.python.org/3/library/struct.html

Al codificar los nombres de las formaciones a utf-8, "Vidoño" tiene 6


letras; pero en utf-8 la ñ ocupa 2 bytes, por lo tanto "Vidoño " de
8 caracteres se traduce a 9 bytes en utf-8.
Igualmente "Guárico " de 8 caracteres se traduce a 9 bytes en utf-8
debido a la á acentuada.
Sin embargo, al momento de empaquetar se especifica "8s", por lo que
struct.pack solo tomará los 8 primeros bytes que se le indican.
Implica que se perderá un espacio en blanco en "Vidoño " y uno en
"Guárico ". (La conversión a utf-8 insertó un byte extra entre las
letras).

finalmente se escribe el paquete binario.


El archivo escrito debe tener (8+8)*4 = 64 bytes
En la parte de lectura se comienza por inicializar en blanco dos
listas: una para los nombres de formaciones y otra para las
velocidades. (form y vel)

Se abre el archivo en modo lectura binaria ("rb")

Se lee en un lazo while infinito, del cual se sale mediante un break


cuando el resultado de la lectura sea una cadena vacía (al llegar al
final del archivo).

Se realiza la operación de desempaquetado con struct.unpack, la cual


siempre devuelve una tupla; en este ejemplo llamada datos.
Se utiliza el mismo formato "8sd" para desempaquetar que se utilizó
para empaquetar.

Igualmente, se decodifican los caracteres con la misma codificación


utf-8.

Los elementos de la tupla se reparten entre la lista de nombres y la


lista de velocidades.

El resultado de la lista de nombres es:


form  ['San Juan', 'Caratas ', 'Vidoño ', 'Guárico']
Notar que "Vidoño " solo tiene un espacio en blanco en lugar de 2, y
"Guárico" no tiene ninguno, en lugar de 1. Eso se debió a la
inserción de un carácter extra en la codificación a utf-8, pero se
empaquetaron 8 bytes. Con ello se perdió 1 byte correspondiente a un
espacio en blanco en Vidoño y Guárico.
Este es un problema con la codificación utf-8. Aunque al momento de
empaquetar se puede tomar en cuenta los bytes extras generados - por
ejemplo usando len(formab) -, no hay forma de determinar cuantos
bytes corresponden a caracteres al momento de leer del archivo
binario.
Una alternativa es agregar un entero indicando cuantos bytes de
caracteres siguen. Pero esto incrementa el tamaño del archivo.
Otra alternativa, es usar codificación "latin-1", la cual mantiene
siempre 1 carácter = 1 byte, pero no permite juegos de mas de 256
caracteres (aunque pocas veces se requiere mas de 256).

En Python los escalares enteros pueden tener una cantidad arbitraria


de dígitos. Por lo tanto, sólo los enteros que sean representables a
lo sumo con 8 bytes (long long) podrán ser empaquetados o
desempaquetados con las funciones del módulo struct.
Enteros que necesiten mas de 8 bytes podrán ser guardados en archivos
como cadenas de texto de sus dígitos decimales, pero esto es muy
ineficiente.
métodos seek, tell

El método tell sirve para indicar la posición del puntero de archivo.


El puntero de archivo es un número en bytes que indica la posición
del último byte leido o escrito. El próximo byte a ser leido o
escrito es el número del puntero + 1
Ejemplo:
ida=open("velocidades.txt",mode="rt",encoding="utf-8")
ida.tell()  0 (posición inicial del puntero en 0)
ida.readline()  'San Juan 1200\n' (lee la primera línea)
ida.tell()  16 (puntero en último byte leido)
ida.seek(32)  (pone el puntero de archivo en byte 32)
ida.readline()  'Vidoño 2100\n' (lee tercera línea)

En la lectura de líneas se incluye también los caracteres no visibles


de fin de línea. En el caso de Windows son dos caracteres, mientras
que en Linux y Mac es sólo un caracter.
El número de bytes puede ser mayor que el número de caracteres si la
codificación es utf-8 y contiene caracteres no ascii, como ñ, letras
acentuadas, diéresis y signos de apertura interrogación y admiración.

En la instrucció seek, se puede indicar el reposicionamiento del


puntero de forma relativa.
De forma predeterminada es relativa al comienzo de archivo, pero se
puede reposicionar respecto a la posición actual o respecto al final
del archivo.
ida.seek(n,0) reposiciona n bytes respecto a inicio de archivo
ida.seek(n,1) reposiciona n bytes respecto a posición actual
ida.seek(n,2) reposiciona n bytes respecto al final del archivo
ida.seek(0,2)  66 tamaño del archivo en bytes

Codificaciones de caracteres
https://docs.python.org/2.4/lib/standard-encodings.html

http://www.joelonsoftware.com/articles/Unicode.html

La codificación ascii está limitada al idioma Inglés y no tiene


caracteres acentuados, ñ, ¿, ¡
La codificación que abarca todos los idiomas es utf8 y es la
recomendable, pero los caracteres especiales castellanos ocupan 2
bytes. La siguiente que abarca los caracteres de los idiomas
occidentales es latin-1 y cp1252 que son iguales (cp1252 es la
designación en Windows). cp850 es la codificación asociada a los
teclados para producir caracteres especiales usando las teclas Alt y
el teclado numérico.

letras='Á','É','Í','Ó','Ú','á','é','í','ó','ú','Ñ','ü','Ñ','ñ','¿','¡
'
print(" Codificacion de caracteres en Python")
print(" utf-8 latin-1 cp1252 cp850")
for c in letras:
print(c,bytes(c,"utf8"),bytes(c,"latin-
1"),bytes(c,"cp1252"),bytes(c,"cp850"))

Funciones importadas
Al igual que otros lenguajes de programación Python cuenta con una
gran cantidad de funciones externas, que se almacenan en "módulos"
temáticos. Los módulos son objetos.

Un módulo se puede crear simplemente como un archivo .py que contenga


definidas funciones y/o constantes. Es análogo a una biblioteca, sólo
que el código no está compilado en lenguaje máquina.
Las funciones dentro de un módulo son métodos, y los objetos
constantes son propiedades.

Un paquete es un directorio que debe contener un archivo especial


llamado: __init__.py y opcionalmente módulos y otros paquetes.
El archivo __init__.py puede estar vacío. Sirve para indicar que el
directorio es un paquete (espacio de nombres).

Los módulos pueden ser provistos por la fundación Python.org, por


otras organizaciones como compañías, universidades o particulares.
También el usuario puede crear sus própios módulos.

Una lista ordenada alfabéticamente de los módulos provistos por


Python.org:
https://docs.python.org/3/py-modindex.html

Ordenados por tema:


https://wiki.python.org/moin/UsefulModules

Los de SciPy.org:
http://www.scipy.org/

Los del paquete Anaconda de la compañía Continuum.io


http://docs.continuum.io/anaconda/pkg-docs

Algunos módulos son:

math Funciones matemáticas de argumento real


cmath Funciones matemáticas de argumento complejo
numpy Funciones matemáticas para arreglos
scipy Mas funciones matemáticas para arreglos
simpy Funciones para álgebra simbólica
mpmath Funciones matemáticas para precisión arbitraria
gmpy2 Funciones matemáticas para precisión arbitraria
matplotlib Funciones de graficación 2D
mpl_toolkits Funciones de graficación 3D
statistics Funciones estadísticas básicas
pandas Funciones para análisis de datos, series de tiempo
random Funciones para números aleatorios
time Funciones para medición de tiempo
pdb Funciones para depuración de guiones Python
sys Funciones para excepciones
os Funciones del sistema operativo
struct Funciones para crear estructuras tipo C
getopt Funciones para reparto de argumentos en guiones
argparse Funciones para reparto de argumentos en guiones
fileinput Funciones especiales para lectura de archivos
re Funciones para expresiones regulares

Hay varios métodos para importar funciones de un módulo o paquete.

Forma 1
Importar funciones individuales de un paquete
Ejemplo: importar las funciones coseno, seno y tangente del módulo
math:

from math import cos, sin, tan


cos(3)  -0.9899924966004454

Con este método se utiliza directamente el nombre de las funciones


importadas.
El problema es que pueden existir funciones definidas por el usuario
o en otros módulos con el mismo nombre.
El usuario debe estar pendiente para que esto no ocurra. Si se
importa una función con el nombre de una preexistente, Python usará
la función importada mas reciente.

Forma 2
Importar funciones de un módulo con un alias
Ejemplo:

from math import cos as coseno, sin as seno, tan as tangente


coseno(3)  -0.9899924966004454

Importar funciones con otro nombre puede ser útil para evitar
coincidencia de nombre con una función de otro paquete o para
simplificar el nombre.
Forma 3
Importar el módulo sin especificar las funciones

Ejemplo:
import math
math.cos(3)  -0.9899924966004454
math.sin(math.pi/2)  1.0

De esta forma, todas las funciones del módulo math están disponibles,
pero cada función debe ser referenciada con el nombre del módulo, un
punto y nombre de la función.
En el ejemplo math.pi es una constante igual al número pi.
Este método tiene la ventaja de que no habrá coincidencia de
funciones con el mismo nombre en diferentes módulos, porque se
diferencian por el nombre del módulo.

También se puede importar el módulo con un alias, por ejemplo:


import math as mat
mat.cos(3)  -0.9899924966004454

Forma 4
Importar todas las funciones de un módulo

from math import *


cos(3)  -0.9899924966004454

Esta forma es desaconsejada porque importa todos los nombres de


funciones del módulo. Esto incrementa la posibilidad de coincidencia
de nombres con funciones propias o de otros módulos.

Lista de funciones y constantes de un módulo


La lista de propiedades de un módulo se puede obtener -después de
haber sido importado- con la función dir (igual que cualquier otro
objeto).
Ejemplo:
import math
dir(math)

Importando de un paquete
Se referencia mediante la sintaxis de puntos:
paquete.módulo.función

Ejemplo:
Importar del paquete "geofisica", módulo "sismicos" la función "Dix"
from geofisica.sismicos import Dix

Importar el módulo sísmicos:


import geofisica.sismicos
ó
from geofisica import sismicos (importa módulo sismicos)

Funciones definidas por el usuario


Forma 1
Funciones definidas dentro del programa fuente:
El el archivo del código fuente de un programa Python se pueden
definir funciones, las cuales son "visibles" en el programa principal
y en las demás funciones en el archivo.
Una función se define mediante la instrucción "def", el nombre de la
función y especificando los argumentos formales entre paréntesis.
Si la función no tiene argumentos de todas formas deben ponerse los
paréntesis.
Las funciones deben definirse antes de usarse por primera vez, por
ello es conveniente que se pongan al comienzo del programa.

def f1(x,y):
p=f2(x)
q=f3(y)
return p*q

def f2(a):
return a*a

def f3(b):
return pow(b,0.5)

s=14
t=9
r=f1(s,t)
print(r)

Observaciones:
La instrucción def inicia un bloque con : en la línea inicial. Las
demás instrucciones deben tener sangría.
La función puede retornar cero, uno o mas valores
La función termina cuando encuentra una instrucción return
Una función puede tener una o mas instrucciones return

Los argumentos de la función pueden ser obligatorios, etiquetados,


predeterminados y variables
Obligatorios son argumentos que se deben suministrar en la misma
cantidad y orden especificados en la definición de la función.
Etiquetados permiten pasar los argumentos en orden distinto al de la
definición, por ejemplo:
f1(y=14,x=9)  303.074…
Predeterminado utiliza un valor prefijado si el argumento no se pasa
al llamar la función
def f1(x,y=16):
En una llamada con f1(5), asignará x=5 y supondrá que y=16

Variables es una tupla de valores de longitud arbitraria que se puede


pasar o no después de los argumentos obligatorios. Se indica
precediéndola con un asterisco.
def fvar(x,y,*z):
fvar(24,18) (llamada sólo con los argumentos obligatorios)
fvar(24,18,9,12,5) (llamada con obligatorios y 3 variables)
Dentro de la función los elementos de z se accesan de la forma usual
mediante índices: z[0], z[1], …

Forma 2
Funciones de usuario separadas en archivos individuales. Cada archivo
constituye un módulo con un solo método.
Supongamos que la función f1 se define y guarda en un archivo llamado
fu1.py
Igualmente f2 se define y guarda en fu2.py y f3 en fu3.py
Para poder usar estas funciones es necesario importarlas antes de
usarlas en cualquier otro programa principal o función.
Por ejemplo es necesario importar f2 y f3 en f1. Pero f2 se encuentra
en el archivo fu2.py y f3 en el archivo fu3.py:

def f1(x,y):
import fu2,fu3
p=fu2.f2(x)
q=fu3.f3(y)
return p*q

En el programa principal es necesario importar f1, que se encuentra


en fu1.py:

import fu1
s=14
t=9
r=fu1.f1(s,t)
print(r)

En este ejemplo se dispuso una sola función por archivo, pero es mas
útil como módulo si se definen en un mismo archivo diversas funciones
con relación a algún tema.
Las funciones a importar deben estar en la ruta de búsqueda de
módulos de Python, el cual suele incluir el directorio actual.
FUNCIONES MATEMÁTICAS

Las funciones matemáticas internas de Python son muy pocas: pow, abs,
complex, sum, max, min, divmod, round.
Se agregan los atributos real, imag y el método conjugate de
escalares números complejos.
Para disponer de otras funciones matemáticas y de métodos numéricos
es necesario importarlas de módulos especializados.
Algunos de estos módulos son:

Módulo Contenido Vectorial Complejos Dígitos


Básicas
math No No 17
reales
Básicas
cmath reales y No Si 17
complejas
Básicas y
numpy métodos Si Si 17
numéricos
numpy mas
scipy funciones Si Si 17
adicionales
Básicas
reales y
mpmath complejas No Si arbitrario
Métodos
numéricos
Básicas
reales y
gmpy2 complejas No Si arbitrario
Métodos
numéricos

Vectorial se refiere a si las funciones puede tomar como argumento un


arreglo y producir como resultado otro arreglo de igual dimensión,
donde la función es aplicada a cada uno de los miembros del arreglo.
Complejos si las funciones pueden tomar argumentos complejos.
Dígitos se refiere al número de dígitos de precisión de escalares en
punto flotante en las operaciones. Realmente es un valor aproximado
que oscila entre 16 y 17.
La precisión de Python para operaciones que produzcan enteros es
arbitraria y no requiere funciones de un módulo especial.

Algunas de estas funciones están definidas en todos estos módulos,


por ejemplo la función coseno está en los módulos math, cmath, numpy,
mpmath y gmpy2. Se pueden usar todas en un mismo programa, siempre
que se especifique el módulo o se le proporcione un alias al
importarlas.
math proporciona las funciones básicas usuales: raiz cuadrada,
trigonométricas, exponenciales, logarítmicas y gamma.
También los números e, pi
Sólo aceptan y producen resultados reales en punto flotante.

cmath contiene las mismas funciones que math pero acepta argumentos
complejos y puede producir resultados complejos.

numpy es mucho mas amplio en cantidad de funciones matemáticas y


además proporciona funciones para métodos numéricos, tales como
solución de sistemas de ecuaciones, cálculo de raices, integración
numérica, operaciones con matrices, etc.
Además las funciones son vectoriales, en el sentido de que aceptan
com argumento un arreglo. El resultado generalmente es otro arreglo
donde la función se aplica a cada miembro de dicho arreglo.

scipy agrega mas funciones y métodos numéricos a numpy, entre ellas


las funciones especiales: Airy, elípticas, Bessel, Riccati, Struve,
gamma, error, Fresnel, Legendre, polinomios ortogonales,
hipergeométrica, Mathiew, esferoidales, combinatoria, estadísticas,
etc.

mpmath es un módulo de funciones para argumentos y resultados de


precisión arbitraria. Opera con números reales o complejos, pero no
es vectorial.
Tiene mayor cantidad de funciones que math y cmath pero menor que
numpy.
mpmath no forma parte del conjunto normal de módulos de Anaconda,
pero se puede importar de la red, desde una ventana de cónsola del
sistema operativo con:

conda import mpmath (conda en: C:\pyzo2015a\Scripts\conda.exe)

gmpy2, originalmente denominado gmpy, es un módulo que comenzó como


precisión arbitraria para enteros, pero fue extendida a flotantes y
complejos en gmpy2. Similar a mpmath, pero todavía no tiene tantas
funciones.
No es parte de Anaconda. Tiene instalador en Windows.
Otros módulos de precisión arbitraria, no tan completos como mpmath y
gmpy2 son: decimal, bigfloat y PyGMP.

¿Cuál módulo usar?


Las funciones mas rápidas son las de math. Es conveniente usarlas con
escalares.
Si se requieren números complejos se utiliza cmath.
Si se opera con arreglos grandes, son mas eficientes las funciones de
numpy y scipy.
Si se requiere precisión arbitraria se usarán las de mpmath o gmpy2.
Ejemplo con escalar
Calcular el coseno de x con funciones de estas bibliotecas:
import math, cmath, numpy, mpmath, gmpy2
pi=math.pi
x=pi/4
math.cos(x)  0.7071067811865476
cmath.cos(x)  (0.7071067811865476-0j)
numpy.cos(x)  0.70710678118654757
mpmath.cos(x)  mpf('0.70710678118654757')
gmpy2.cos(x)  mpfr('0.70710678118654757')

Ejemplo con arreglo


pi=math.pi
x=[pi/3,pi/4,pi/6]
[math.cos(t) for t in x]  [0.5000000000000001,
0.7071067811865476,
0.8660254037844387]
[cmath.cos(t) for t in x]  [(0.5000000000000001-0j),
(0.7071067811865476-0j),
(0.8660254037844387-0j)]
numpy.cos(x)  array([ 0.5 , 0.70710678, 0.8660254 ])
[mpmath.cos(t) for t in x]  [mpf('0.50000000000000011'),
mpf('0.70710678118654757'),mpf('0.866
02540378443871')]

En las funciones no vectoriales se empleó una comprensión para


obtener el arreglo resultado. Sólo numpy acepta directamente como
argumento una lista

Algebra de precisión arbitraria.


mpmath.mp.dps=30 (establece 30 dígitos de precisión)
x=mpmath.pi/4 (argumento con 30 dígitos de precisión)
mpmath.cos(x)  mpf('0.707106781186547546049745767992148')
Paquete Numpy
Contiene funciones matemáticas y de métodos numéricos. Aceptan
arreglos como argumento e igualmente devuelven arreglos como
resultado.
Las funciones de Numpy producen objetos clase "Numpy array".

Para hacer uso de las funciones de Numpy es necesario incluir la


instrucción:
import numpy

Se acostumbra importarla con el seudónimo np:


import numpy as np

En lo que sigue se supone que se ha importado Numpy en una de las dos


formas indicadas.

Numpy tiene sus propios arreglos llamados Numpy array


Los arreglos Numpy tienen la ventaja de tener métodos muy útiles que
no poseen las listas y tuplas.
Los Numpy array son contenedores mutables, numerables, cuyos miembros
son todos escalares del mismo tipo; por ejemplo todos enteros, todos
punto flotante o todos caracteres.
Esto los diferencia de las listas y tuplas cuyos miembros pueden ser
de diferente tipo.
Los miembros de un Numpy array se referencian igual que las listas y
tuplas mediante índices, comenzando desde 0. También aceptan índices
negativos.
Los operadores + y * con arreglos numpy se interpretan como suma y
multiplicación algebraicas puntuales, si la operación es válida, sinó
como concatenación.
Para concatenar arreglos Numpy se debe usar la función numpy.append()
o la función numpy.concatenate().
La mayoría de las funciones de Numpy también aceptan como argumento
arreglos ordinarios como listas y tuplas, siempre que sus miembros
sean todos del tipo esperado por la función.

Creación de un Numpy array


Se crea con la función numpy.array o con otra función que produzca
como resultado un Numpy array.
Ejemplo:
x=[2,3,5,7] (lista de enteros)
xe=numpy.array(x) (creación con copia del arreglo Numpy enteros xe)
xe=numpy.asarray(x) (creación del arreglo Numpy enteros xe)
xf=numpy.array(x,dtype="float") (arreglo Numpy de flotantes xf)
xc=numpy.array(x,dtype="str") (arreglo Numpy de caracteres xc)
Tipos no numéricos: "str", "bytes", "bool"

Forma alternativa mediante funciones específicas para cada tipo


x=[2,3,5,7] (lista de enteros)
xe=numpy.int_(x) (creación del arreglo Numpy enteros xe)
xf=numpy.float_(x) (arreglo Numpy de flotantes xf)
xc=numpy.str(x) (cadena de caracteres de la lista)

Nota 1:
numpy.int_ sólo acepta enteros dentro del rango de valores de enteros
tipo intc

Nota 2:
numpy.array(x,dtype="str") ≠ numpy.str(x) = x.__str__()

La primera crea un arreglo donde cada elemento es una cadena; las


segundas crean una sola cadena con todo el arreglo, incluyendo los
corchetes o paréntesis.

También se pudieron haber creado los arreglos utilizando como


argumento una tupla.

De igual forma que otros objetos mutables, el operador = crea un


duplicado, alias o seudónimo de un arreglo y no una copia
independiente.
Si A es un arreglo numpy:
B=A crea un alias B: modificaciones en B también modifican A.

Tabla de tipos numéricos en Numpy

Tipo Descripción
bool_ Lógico. True o False. 1 byte
int_ Entero predeterminado. Igual a long en C. 32 o 64 bits
intc Entero igual a int en C. 32 o 64 bits
intp Entero para indexado. 32 o 64 bits
byte Entero. Equivale a int8
int8 Entero. Rango: -128 a 127
int16 Entero. Rango: -32768 a 32767
int32 Entero. Rango: -2147483648 a 2147483647
int64 Entero. Rango: -9223372036854775808 a 9223372036854775807
uint8 Entero sin signo. Rango: 0 a 255
uint16 Entero sin signo. Rango: 0 a 65535
uint32 Entero sin signo. Rango: 0 a 4294967295
uint64 Entero sin signo. Rango: 0 a 18446744073709551615
float_ Flotante predeterminado. Equivale a float64
float16 Flotante: signo 1 bit, exponente 5 bits, mantisa 10 bits
float32 Flotante: signo 1 bit, exponente 8 bits, mantisa 23 bits
float64 Flotante: signo 1 bit, exponente 11 bits, mantisa 52 bits
complex Complejo. Equivale a complex128
complex64 Complejo formado por dos flotantes de 32 bits
complex128 Complejo formado por dos flotantes de 64 bits
Todos estos tipos en la tabla se puede usar con el argumento dtype= o
como método Numpy.
Con relación a los métodos Numpy que existen sin guión y con guión
bajo al final del nombre, tales como int, bool, complex, los que
terminan con guión bajo se aplican a arreglos y los que no tienen
guión a escalares.

Rango de enteros y flotantes


El rango de enteros numpy se puede determinar con la función
numpy.iinfo

numpy.iinfo(numpy.int16).min  -32768
numpy.iinfo(numpy.int16).max  32767

El rango y otros parámetros de flotantes se determina con la función


numpy.finfo
numpy.finfo(numpy.float64).max  1.7976931348623157e+308
numpy.finfo(numpy.float64).tiny  2.2250738585072014e-308

Conversión de arreglo Numpy a contenedores básicos


Un arreglo Numpy se puede convertir directamente a cadena de bytes,
lista, cadena de caracteres y archivo con los métodos tobytes,
tolist, tostring y tofile respectivamente.
Ejemplo:
x=[2,3,5,7] lista de enteros
xe=numpy.array(x) arreglo Numpy de enteros xe
xe  array([2, 3, 5, 7]) xe es un arreglo Numpy
xe.tolist()  [2,3,5,7] conversión a lista con método tolist

Conversión de tipo en arreglo Numpy


Un arreglo Numpy cuyos miembros son de un determinado tipo se puede
convertir a otro arreglo Numpy de tipo diferente, mediante el método
astype, siempre que la conversión sea válida.
Como argumento se puede usar uno de la tabla de tipos Numpy.

Ejemplo: conversión Numpy array tipo entero a tipo flotante:


xe  array([2, 3, 5, 7]) xe es un arreglo Numpy tipo entero
xe.astype("float")  array([ 2., 3., 5., 7.]) arreglo de flotantes

Ejemplo: conversión Numpy array tipo cadena de caracteres a flotante:


xcf=numpy.array(["3.48","-17.6","0.25"]) xcf es array tipo string
xcf  array(['3.48', '-17.6', '0.25'], dtype='<U5')

xff=xcf.astype("float")
xff  array([ 3.48, -17.6 , 0.25])

Ejemplo: conversión de Numpy array tipo flotante a entero:


xff.astype("int")  array([ 3, -17, 0]) trunca los decimales al
hacer la conversión

Ejemplo: conversión de Numpy array tipo flotante a complejo:


xff.astype("complex")  array([ 3.48+0.j, -17.60+0.j, 0.25+0.j])

Ejemplo: conversión no válida de Numpy array tipo caracteres a entero


xcf  array(['3.48', '-17.6', '0.25'], dtype='<U5')
xcf.astype("int")  error debido al punto de los decimales
xcf.astype("float").astype("int")  array([ 3, -17, 0])
la conversión primero a flotante y después a entero si funciona.

Operaciones algebraicas con arreglos numéricos


Todas las operaciones algebraicas entre arreglos numéricos Numpy de
iguales dimensiones son puntuales elemento a elemento.

x1=numpy.array([2,3,5])
x2=numpy.array([7,11,13])
x1+x2  array([ 9, 14, 18]) (suma puntual, no concatena)
x1*x2  array([14, 33, 65]) (producto puntual)
x2/x1  array([ 3.5 , 3.66666667, 2.6 ])
x2**x1  array([ 49, 1331, 371293], dtype=int32)
x2%x1  array([1, 2, 3], dtype=int32)

Las operaciones con escalares son del escalar con cada elemento del
arreglo:
3+x1  array([5, 6, 8])
3*x1  array([ 6, 9, 15]) (producto puntual, no concatena)
x1/3  array([ 0.66666667, 1. , 1.66666667])
3/x1  array([ 1.5, 1. , 0.6])
3**x1  array([ 9, 27, 243], dtype=int32)
x1**3  array([ 8, 27, 125], dtype=int32)
x1%3  array([2, 0, 2], dtype=int32)
3%x1  array([1, 0, 3], dtype=int32)

Funciones de arreglos numéricos Numpy

Las funciones también se aplican puntualmente a los elementos de


contenedores lista, tupla y arreglo Numpy.

Aplicando una función numpy a una lista y a un arreglo Numpy:


x  [2, 3, 5, 7] (lista)
numpy.sqrt(x) 
array([ 1.41421356, 1.73205081, 2.23606798, 2.64575131])

xe  array([2, 3, 5, 7]) (arreglo Numpy)


numpy.sqrt(xe) ) 
array([ 1.41421356, 1.73205081, 2.23606798, 2.64575131])

En este ejemplo el resultado es idéntico e igual a un arreglo Numpy.

Si el argumento es un arreglo de números reales, pero la función


produce resultados complejos, entonces debe convertirse primero el
argumento a complejo, sinó el resultado será nan (not a number).
Ejemplo:
x=numpy.array([-2,-3,-5,-7])
numpy.sqrt(x)  array([ nan, nan, nan, nan])

numpy.sqrt(x.astype("complex")) 
array([ 0.+1.41421356j, 0.+1.73205081j, 0.+2.23606798j,
0.+2.64575131j])

Otra forma:
numpy.sqrt(x+0j) 
array([ 0.+1.41421356j, 0.+1.73205081j, 0.+2.23606798j,
0.+2.64575131j])

numpy.sqrt(numpy.complex_(x)) 
array([ 0.+1.41421356j, 0.+1.73205081j, 0.+2.23606798j,
0.+2.64575131j])

Arreglos Numpy multidimensionales

Se pueden crear a partir de sus equivalentes como listas y tuplas,


o redimensionando arreglos Numpy. No es necesario que sean
rectangulares.

Ejemplos:

A=numpy.array([[1,2], [3,4], [5,6]]) (arreglo 2D de 3 filas x


2 columnas)
A=numpy.array([1,2,3,4,5,6]).reshape((3,2)) (lo mismo, partiendo de
una lista 1D)

A  array([[1, 2],
[3, 4],
[5, 6]])

Matrices:
M=numpy.matrix([[1,2], [3,4], [5,6]]) (matriz)
M  matrix([[1, 2],
[3, 4],
[5, 6]])

El arreglo 2D y la matriz pueden ser no rectangulares, pero entonces


ciertas operaciones algebraicas no serán válidas.
Aunque el arreglo 2D y la matriz parecen lo mismo, estrictamente no
lo son. La matriz es un objeto que posee métodos adicionales propios
en el sentido matemático. Además las operaciones de multiplicación
con el operador * siguen las reglas de multiplicación escalar de
matrices, mientras que con el arreglo 2D se interpreta como
multiplicación puntual.
Por otra parte las matrices están limitadas a 2 dimensiones, mientras
que los arreglos pueden ser de mas de 2 dimensiones.
La referencia o cambio de un elemento de objeto matrix mediante
índices tiene una sintaxis diferente.

Ejemplo de diferencia entre arreglos 2D y matrices

Sean:
A=numpy.array([1,2,3,4,5,6]).reshape((3,2)) (arreglo 2D, 3x2)
a=numpy.array([7,8]).reshape((2,1)) (arreglo 2D, 2x1)

M=numpy.matrix(A) (matriz 3x2)


M=numpy.mat(A) (matriz 3x2)(sin copia)
m=numpy.matrix(a) (matriz 2x1)

A  array([[1, 2],
[3, 4],
[5, 6]])

a  array([[7],
[8]])

M  matrix([[1, 2],
[3, 4],
[5, 6]])

m  matrix([[7],
[8]])

Operación de multiplicación escalar de matriz por vector:


M*m  matrix([[23],
[53],
[83]])

m*M  error por no concordancia de las dimensiones

Operación de multiplicación escalar de arreglos 2D:


A*a  error, porque no interpreta la operación como multiplicación
escalar, sinó como multiplicación puntual y las dimensiones no
concuerdan y no es posible hacer expansión de c.
A.dot(a)  array([[23],
[53],
[83]])

Es necesario usar el método dot de arreglos para efectuar


multiplicación escalar. (Las dimensiones deben ser concordantes).

Si en la operación uno de los arreglos es matriz y el otro arreglo


2D, Python promueve el arreglo 2D a matriz para que la operación
resulte exitosa:

M*a  matrix([[23], B: matriz, a: arreglo 2D


[53],
[83]])

A*m  matrix([[23], A: arreglo 2D, m: matriz columna


[53],
[83]])

Referencia y cambio de elementos en objeto matrix:


A  array([[1, 2],
[3, 4],
[5, 6]])
M  matrix([[1, 2],
[3, 4],
[5, 6]])

A[0][1]  2 (válido: elemento 1 existe)


M[0][1]  error (no válido: elemento 1 no existe)
M[0]  matrix([[1, 2]]) (produce objeto matrix de una fila)

A[0,1]  2
M[0,1]  2

A[0,:]  array([1, 2]) (arreglo fila, es objeto 1D)


M[0,:]  matrix([[1, 2]]) (matriz fila, es objeto 2D)

A[0].item(1)  2 (escalares se obtienen con método item)


M[0].item(1)  2 (escalares se obtienen con método item)

A.item((1,1))  4 (otra forma especificando fila, columna)


M.item((1,1))  4 (especificando fila, columna)

A.item(4)  5 (contando en arreglo aplanado por filas)


M.item(4)  5 (contando en matriz aplanada por filas)
A.itemset((2,0),11)  array([[1, 2], (asignando por fila, columna)
[3, 4],
11, 6]])
M.itemset((2,0),11)  matrix([[1, 2], (asignando por fila, columna)
[3, 4],
[11, 6]])

A[2].itemset(0,13)  array([[1, 2],


[3, 4],
[13, 6]])
M[2].itemset(0,13)  matrix([[1, 2],
[3, 4],
[13, 6]])

A.itemset(4,17)  array([[1, 2], (asignando por arreglo aplanado)


[3, 4],
[17, 6]])
M.itemset(4,17)  matrix([[1, 2], (asignando por matriz aplanada)
[3, 4],
[17, 6]])

Algunos métodos exclusivos de arreglo matriz:


M.I  matriz inversa (o pseudoinversa si arreglo rectangular)
M.H  transpuesta hermítica
M.A1  linealiza por filas matriz M a un arreglo Numpy 1D
M.A  convierte matriz M a arreglo Numpy 2D (función inversa de
numpy.matrix)

Métodos equivalentes:
M.getI == M.I
M.getH == M.H
M.getA1 == M.A1
M.getA == M.A == numpy.asarray(M)

Referencia a elementos de un arreglo Numpy


Si un arreglo Numpy es rectangular, se puede utilizar el mismo
procedimiento de referencia que listas y tuplas, mediante índices,
secciones y comprensiones.

Ejemplos:
A[2,1]  6 (elemento fila 2, columna 1)
A[2][1]  6 (elemento fila 2, columna 1)
A[1]  array([3, 4]) (fila 1, contando desde 0)
A[1:2]  array([3, 4]) (fila 1, notar que no incluye la fila 2)
A[:2]  array([[1, 2], (filas 0 y 1)
[3, 4]])
A[:,0]  array([1, 3, 5]) (columna 0, el arreglo resultante es 1D)
M[:,0]  matrix([[1], (columna 0, el arreglo resultante es una
[3], matriz columna)
[5]])

O también con el método item:


A.item(5)  6 (conteo linealizado por filas)
A.item(-5)  2 (conteo en reversa linealizado por filas)
A.item((2,1))  6 (indicando fila y columna en una tupla)

Algunos métodos de arreglos Numpy


Ejemplos:
A=numpy.array([2,3,5,7,11,13,17,19,23]).reshape(3,3) (arreglo 3x3)
array([[ 2, 3, 5],
[ 7, 11, 13],
[17, 19, 23]])

Transpuesta
Forma 1
A.T  array([[ 2, 7, 17], (transpuesta de arreglo)
[ 3, 11, 19],
[ 5, 13, 23]])

Nota: la transpuesta solo funciona si el arreglo es 2D o matriz.


Si es un arreglo 1D no produce ningún cambio.
numpy.array([2,3,5,7]).T  array([2, 3, 5, 7])

Forma 2
A.swapaxes(1,0)  array([[ 2, 7, 17], (transpuesta de arreglo)
[ 3, 11, 19],
[ 5, 13, 23]])

Ceros, vacíos
Determina si al menos uno de los miembros de A produce lógico True.
Si los elementos no son lógicos, realiza la conversión habitual donde
numéricos 0 y cadena vacía produce False y todo lo demás produce
True.
Si no se especifica el eje, aplica a todo el arreglo.
A.any()  True
A.any(axis=0)  array([ True, True, True], dtype=bool)(por columnas)

Determina si todos los miembros de A producen lógico True. Si no se


especifica el eje, aplica a todo el arreglo.
A.all() True
Suma y producto de elementos
Obtiene la suma o el producto de todos los elementos del arreglo,
pero se puede especificar suma o producto por filas o columnas.

A.sum()  100
A.sum(axis=1)  array([10, 31, 59]) (suma por filas)
A.prod()  223092870
A.prod(axis=0)  array([ 238, 627, 1495]) (producto por columnas)

Suma y productos acumulados


Produce suma acumulativa, equivalente a una integración discreta.
También producto acumulado.
Si no se especifica el eje lo aplica a todo el arreglo, en orden de
filas.
A.cumsum()  array([ 2, 5, 10, 17, 28, 41, 58, 77, 100],
dtype=int32)

Acumulado por columnas:


A.cumsum(axis=0)  array([[ 2, 3, 5],
[ 9, 14, 18],
[26, 33, 41]], dtype=int32)

A.cumprod()  array([ 2, 6, 30, 210, 2310, 30030,


510510, 9699690, 223092870], dtype=int32)

Diagonales del arreglo


Produce un arreglo 1D constituido por los elementos de la diagonal
principal, pero se puede especificar cualquier otra diagonal.
A.diagonal()  array([ 2, 11, 23]) (diagonal principal o 0)
A.diagonal(offset=1)  array([ 3, 13]) (diagonal 1)

Producto escalar
Los arreglos deben ser concordantes para que funcione
A.dot([1,2,3])  array([ 23, 68, 124])

Llenar un arreglo con valor constante


El arreglo debe existir previamente y cada uno de sus elementos será
sustituido por un valor constante.

x=numpy.array([1,2,3])  array([1, 2, 3])


x.fill(69)  array([69, 69, 69]) (elementos sustituidos por 69)

Si el arreglo no existe se puede crear mediante una lista:


x=numpy.array([69]*3)  array([69, 69, 69])

Mínimo, máximo, media y desviación típica de un arreglo


Calcula parámetros estadísticos, para todo el arreglo, o si se
especifica, por filas o columnas.
A.min()  2
A.max()  23
A.max(axis=0)  array([17, 19, 23]) (máximo por columnas)
A.mean()  11.111111111111111 (media)
A.std()  7.0307964531361664 (desviación típica)

Traza
Obtiene la traza del arreglo, consistente en la suma de los elementos
de la diagonal principal o de cualquier otra diagonal especificada.
A.trace()  36 (traza de la diagonal principal)

Repetición de elementos, filas o columnas


Produce otro arreglo con los elementos, filas o columnas repetidos
una cantidad especificada de veces.
Arreglo linealizado repetido una vez (equivale a A.flatten()):
A.repeat(1)  array([ 2, 3, 5, 7, 11, 13, 17, 19, 23])

Arreglo linealizado repetido dos veces:


A.repeat(2)  array([ 2, 2, 3, 3, 5, 5, 7, 7, 11, 11, 13, 13, 17,
17, 19, 19, 23, 23])

Columnas repetidas 2 veces:


A.repeat(2,axis=1)  array([[ 2, 2, 3, 3, 5, 5],
[ 7, 7, 11, 11, 13, 13],
[17, 17, 19, 19, 23, 23]])

Cambio del tamaño de las dimensiones de un arreglo


Método reshape
Cambia el tamaño de las dimensiones de un arreglo. El producto de las
dimensiones del nuevo arreglo debe ser igual al del original.
Por ejemplo, si un arreglo tiene dimensiones 3x4 el nuevo arreglo
puede tener dimensiones válidas 1x12, 2x6, 3x4, 4x3, 6x2, 12x1
A.reshape(1,9)  array([[ 2, 3, 5, 7, 11, 13, 17, 19, 23]])

Notar que en este ejemplo el arreglo resultante sigue teniendo el


mismo número de dimensiones que el arreglo original, aún cuando el
número de filas o columnas sea sólo 1. No es equivalente a flatten el
cual produce una copia 1D. Sin embargo, reshape puede cambiar un
arreglo 1D a otro de mayores dimensiones.

Método resize
Cambia insitu las dimensiones de un arreglo. La diferencia con
reshape es que no crea una copia, sinó que modifica las dimensiones
del objeto original. Con el operador = produce un objeto NoneType

Linealizado o aplanado de un arreglo


Toma como argumento un arreglo y devuelve un arreglo 1D con los
mismos elementos.
Hay dos métodos para ello: flatten y ravel
flatten devuelve una copia independiente.
ravel devuelve un duplicado o alias que comparte elementos.
ACopia1D=A.flatten()  array([ 2, 3, 5, 7, 11, 13, 17, 19, 23])
ADupli1D=A.ravel()  array([ 2, 3, 5, 7, 11, 13, 17, 19, 23])
ADupli1D[8]=-1  array([ 2, 3, 5, 7, 11, 13, 17, 19, -1])
A  array([[ 2, 3, 5],
[ 7, 11, 13],
[17, 19, -1]]) (el elemento 2,2 de A cambió a -1)

A.flatten() equivale a A.repeat(1) ó numpy.hstack(A)

Modificación de elementos linealizada


Cambia insitu valores asignando mediante linealizado de los índices
por filas.
A.put((2,4,6),(-5,-11,-17))
A  array([[ 2, 3, -5],
[ 7, -11, 13],
[-17, 19, 23]])

Incremento de dimensiones de un arreglo


Produce un nuevo arreglo con una dimensión adicional
x=[1,2,3] (arreglo 1D)
numpy.expand_dims(x,0) 
array([[1, 2, 3]]) (arreglo 2D, en eje 0)

numpy.expand_dims(x,1) 
array([[1], (arreglo 2D, en eje 1)
[2],
[3]])

Las siguientes solo funcionan si el argumento es un arreglo numpy:


x=numpy.array([1,2,3])
x[numpy.newaxis] 
array([[1, 2, 3]]) (arreglo 2D, en eje 0)

x[:,numpy.newaxis] 
array([[1], (arreglo 2D, en eje 1)
[2],
[3]])

Dimensiones de un arreglo
Devuelve una tupla con las dimensiones del arreglo
A.shape  (3,3)

Tamaño de un arreglo
Indica la cantidad total de elementos del arreglo
A.size  9

Número de dimensiones de un arreglo


Indica el número de dimensiones de un arreglo
A.ndim  2

Métodos para arreglos de números complejos


Obtener parte real:
A.real

Obtener parte imaginaria:


A.imag

Obtener magnitud:
A.__abs__()

obtener conjugado:
A.conj()

Funciones numpy
La cantidad de funciones de Numpy es muy grande. En la versión mas
reciente según len(dir(numpy))tiene al menos 586. Pero en realidad
son mas porque algunos son objetos que contienen otros objetos, como
numpy.linalg, numpy.random
Entre ellas están las habituales:
trigonométricas, hiperbólicas, exponenciales y logarítmicas.
Funciones para números aleatorios, estadísticas, polinomios, álgebra
lineal, matrices

Se pueden obtener funciones de uso menos común con otros módulos de


scipy

Algunas de las mas usadas:

Arreglo todo ceros


Crea un arreglo todo ceros. Se debe especificar dimensiones del
arreglo en una tupla, y opcionalmente el tipo de elementos.
numpy.zeros((2,3),dtype="int") 
array([[0, 0, 0],
[0, 0, 0]])

Arreglo todo unos


Crea un arreglo todo unos. Se debe especificar dimensiones del
arreglo en una tupla, y opcionalmente el tipo de elementos.

numpy.ones((2,3),dtype="int") 
array([[1, 1, 1],
[1, 1, 1]])

Arreglo unidad
numpy.eye(3) 
array([[ 1., 0., 0.],
[ 0., 1., 0.],
[ 0., 0., 1.]])

Arreglo "vacío"
Crea un arreglo vacío, cuyos valores son los que tenga el sector de
memoria reservado para el arreglo en ese momento.
Se debe especificar dimensiones del arreglo en una tupla, y
opcionalmente el tipo de elementos.
numpy.empty((2,3),dtype="int") 
array([[0, 0, 0],
[0, 0, 0]])

Arreglos "como"
Funciones para crear arreglos de todo ceros, todo unos o vacío con
las mismas dimensiones que un arreglo preexistente.
A=numpy.array([[ 47, -17, -96],[-15, -91, -53]])
A 
array([[ 47, -17, -96],
[-15, -91, -53]])

numpy.zeros_like(A) 
array([[0, 0, 0], (arreglo todo ceros de dimensiones como A)
[0, 0, 0]])

numpy.ones_like(A) 
array([[1, 1, 1], (arreglo todo unos de dimensiones como A)
[1, 1, 1]])

numpy.empty_like(A) 
array([[0, 0, 0], (arreglo "vacío" de dimensiones como A)
[0, 0, 0]])

Copia de un arreglo
Los arreglos numpy son mutables. El operador = crea un duplicado del
arreglo, no una copia independiente.
Para crear una copia independiente se usa el método copy o la función
numpy.copy
B=A.copy() con el método copy
B is A  False
B=numpy.copy(A) con la función copy
B is A  False

Arreglo de sucesión aritmética


Incluyendo el punto final:
numpy.linspace(inicio, final, número de valores)
numpy.linspace(10,40,6)  array([ 10., 16., 22., 28., 34., 40.])
(incluye final)
Fórmula del intervalo:
Intervalo = (final-inicial)/(número de puntos – 1)

Excluyendo el punto final:


numpy.linspace(inicio, final, número de valores, endpoint=False)
numpy.linspace(10,40,6,endpoint=False)
 array([ 10., 15., 20., 25., 30., 35.]) (excluye final)

Fórmula del intervalo:


Intervalo = (final-inicial)/(número de puntos)

Arreglo de sucesión geométrica


Incluyendo punto final:
numpy.logspace(exponente inicial, exponente final, número de puntos)
La base predeterminada es 10, pero se puede seleccionar otra.
La función primero obtiene la sucesión aritmética de los exponentes y
después calcula las potencias de 10 con ellos.
numpy.logspace(1,2,3)  array([ 10. , 31.6227766, 100. ])
Equivale a:
numpy.power(10,numpy.linspace(1,2,3))

Excluyendo el punto final:


numpy.logspace(1,2,3,endpoint=False)  array([ 10. , 21.5443469 ,
46.41588834])

Igual a: numpy.logspace(1,2,4) y descartando el último valor

Rango con flotantes


numpy.arange permite obtener rangos con números flotantes o enteros;
en constraste con range que sólo trabaja con enteros
numpy.arange(-1.4,23.68,5.2)  array([ -1.4, 3.8, 9. , 14.2, 19.4])

Arreglos de números aleatorios


El submódulo numpy.random tiene gran cantidad de funciones para
diferentes distribuciones estadísticas: uniforme, normal, binomial,
poisson, chicuadrado, beta, weibull, hipergeométrica, etc.

Aleatorios de distribución uniforme entre 0 y 1


numpy.random.random_sample((2,3)) 
array([[ 0.1769819 , 0.02294939, 0.64857626],
[ 0.17369633, 0.25485781, 0.10111319]])
Sinónimos de esta función:
numpy.random.random, numpy.random.randf, numpy.random.sample

Aleatorios de distribución normal


numpy.random.normal(10,2,(2,3))  (media=10, desviac. tip.=2)
array([[ 10.43484194, 8.83285721, 8.82177312],
[ 10.10506082, 10.00948687, 8.28673884]])
numpy.random.randn(2,3)  (media=0, desv. tip.=1)
array([[-0.09061907, 0.36245437, -1.46061116],
[-0.57726226, -0.75429491, -0.11474497]])

Aleatorios enteros de distribución uniforme en un intervalo


Intervalo [0,100]
numpy.random.random_integers(0,100,(2,3))  array([[59, 14, 69],
[42, 75, 46]])

Traza de arreglo
Calcula la traza de un arreglo. De forma predeterminada según la
diagonal principal.
A=n.random.random_integers(-100,100,(2,3))
A  array([[ 47, -17, -96],
[-15, 91, 53]])
numpy.trace(A)= 138 (47 + 91)
Se recomienda usar el método: A.trace()  -44

Determinante de arreglo
Calcula el determinante de un arreglo numérico 2D cuadrado.
El arreglo puede ser una lista, una tupla o un arreglo numpy.
A=[[1,2,3],[4,5,6],[7,8,0]]

numpy.linalg.det(A)  27.0

Norma de arreglo
De forma predeterminada calcula la norma de Frobenius. En el caso de
listas o tuplas calcula las normas del arreglo linealizado.
En el caso de arreglos Numpy, puede calcular normas por dimensiones,
tal como filas o columnas en el caso de un arreglo 2D.

A=[[1,2,3],[4,5,6],[7,8,0]]
numpy.linalg.norm(A)  14.282856857085701 (norma Frobenius)
numpy.linalg.norm(A,ord=2)  13.201458618948674 (norma cuadrática)
numpy.linalg.norm(numpy.array(A),ord=2,axis=0) (norma 2 por columnas)
 array([ 8.1240384 , 9.64365076, 6.70820393])

Inversa de arreglo 2D
Calcula la matriz inversa de un arreglo numérico 2D cuadrado.
El arreglo puede ser un arreglo numpy, una lista o una tupla, pero el
resultado siempre será un arreglo numpy.
El arreglo debe ser numérico, 2D, cuadrado, no singular.

A=[[-1,4,1],[0,-5,-2],[3,10,6]]
numpy.linalg.inv(A) 
array([[-10., -14., -3.],
[ -6., -9., -2.],
[ 15., 22., 5.]])
Pseudoinversa de arreglo 2D
Calcula la matriz pseudoinversa Moore-Penrose de un arreglo numérico
2D rectangular. Como caso particular, si la matriz es cuadrada y no
singular, entonces la pseudoinversa es igual a la inversa.
El arreglo puede ser un arreglo numpy, una lista o una tupla, pero el
resultado siempre será un arreglo numpy.
El arreglo debe ser numérico, 2D.

Ejemplo con matriz rectangular:


numpy.linalg.pinv([[1,2,3],[4,5,6]]) 
array([[-0.94444444, 0.44444444],
[-0.11111111, 0.11111111],
[ 0.72222222, -0.22222222]])

Ejemplo con matriz singular:


numpy.linalg.pinv([[1,2,3],[4,5,6],[7,8,9]]) 
array([[ -6.38888889e-01, -1.66666667e-01, 3.05555556e-01],
[ -5.55555556e-02, -2.60208521e-16, 5.55555556e-02],
[ 5.27777778e-01, 1.66666667e-01, -1.94444444e-01]])

Nota:
También se puede usar el método I para calcular inversa y
pseudoinversa de un objeto matrix.
Esto funciona bien si el arreglo es rectangular no cuadrado, pero si
es cuadrado intentará calcular la inversa y no la pseudoinversa.

Ejemplo:
Arreglo rectangular, calcula pseudoinversa:
numpy.matrix([[1,2,3],[4,5,6]]).I 
matrix([[-0.94444444, 0.44444444],
[-0.11111111, 0.11111111],
[ 0.72222222, -0.22222222]])

Arreglo cuadrado, calcula inversa. En este ejemplo la matriz es


singular, por lo tanto no tiene inversa. La matriz que resulta es
producto de imprecisión numérica:
numpy.matrix([[1,2,3],[4,5,6],[7,8,9]]).I 
matrix([[ -4.50359963e+15, 9.00719925e+15, -4.50359963e+15],
[ 9.00719925e+15, -1.80143985e+16, 9.00719925e+15],
[ -4.50359963e+15, 9.00719925e+15, -4.50359963e+15]])

Por ello siempre es conveniente determinar la condición de una matriz


cuadrada antes de calcular su inversa, o sinó utilizar siempre la
función de la pseudoinversa, pero que es computacionalmente mas
costosa.

La condición de una matriz se obtiene con:


numpy.linalg.cond([[1,2,3],[4,5,6],[7,8,9]]) 
1.1439441181880765e+17

Cambio de forma
A  array([[ 47, -17, -96],
[-15, 91, 53]])

numpy.reshape(A,(3,2)) 
array([[ 47, -17],
[-96, -15],
[ 91, 53]])

Cambio a arreglo 1D
A  array([[ 47, -17, -96],
[-15, 91, 53]])

numpy.ravel(A)  array([ 47, -17, -96, -15, 91, 53]) (alias)


numpy.flatten(A)  array([ 47, -17, -96, -15, 91, 53]) (copia)

Volteo de arreglo izquierda-derecha


Funciona con arreglos numpy, listas y tuplas, pero el resultado es
siempre un arreglo numpy. Los arreglos tienen que ser de 2 o mas
dimensiones.
A  array([[ 47, -17, -96],
[-15, 91, 53]])

numpy.fliplr(A) 
array([[-96, -17, 47],
[ 53, 91, -15]])

Volteo de arreglo arriba-abajo


Funciona con arreglos numpy, listas y tuplas, pero el resultado es
siempre un arreglo numpy. Los arreglos tienen que ser de 2 o mas
dimensiones.

A  array([[ 47, -17, -96],


[-15, 91, 53]])

numpy.flipud(A) 
array([[-15, 91, 53],
[ 47, -17, -96]])

Rodar elementos, filas o columnas


Funciona con arreglos numpy, listas y tuplas, pero el resultado es
siempre un arreglo numpy

A  array([[ 47, -17, -96],


[-15, 91, 53]])
numpy.roll(A,1) 
array([[ 53, 47, -17], (rodar todo el arreglo un elemento)
[-96, -15, 91]])

numpy.roll(A,1,0) 
array([[-15, 91, 53], (rodar filas una vez hacia abajo)
[ 47, -17, -96]])

numpy.roll(A,2,1) 
array([[-17, -96, 47], (rodar columnas dos veces a la izquierda)
[ 91, 53, -15]])

Rotar un arreglo en saltos de 90 grados


Funciona con arreglos numpy, listas y tuplas, pero el resultado es
siempre un arreglo numpy

A  array([[ 47, -17, -96],


[-15, 91, 53]])

numpy.rot90(A) 
array([[-96, 53], (arreglo rotado 90° antihorario)
[-17, 91],
[ 47, -15]])

numpy.rot90(A,1) 
array([[ 53, 91, -15], (arreglo rotado 180° antihorario)
[-96, -17, 47]])

Matriz diagonal y arreglo diagonal


Si el argumento es un arreglo 1D construye una matriz cuadrada cuya
diagonal principal es dicho arreglo.
Si el argumento es una matriz, entonces el resultado es un arreglo 1D
con la diagonal principal o una paralela

Construcción de matriz diagonal:


numpy.diag([1,2,3]) 
array([[1, 0, 0],
[0, 2, 0],
[0, 0, 3]])

Extracción de diagonal, primera paralela superior:


A=[[1,2,3],
[4,5,6]]
numpy.diag(A,1)  array([2, 6])

Ordenamiento de los elementos de una lista, tupla o arreglo numpy


x= [[3, -10, 0], [-1, -2, 4]]
numpy.sort(x)  array([[-10, 0, 3], (linealiza y ordena por
[ -2, -1, 4]]) columnas de menor a mayor)
numpy.sort(x,axis=0)  array([[ -1, -10, 0], (ordena por columnas)
[ 3, -2, 4]])

Arreglo triangular inferior o superior


Hace ceros los elementos de un arreglo 2D por encima de la diagonal
indicada. El resultado es un arreglo numpy.

x= [[1, 2, 3], [4, 5, 6], [7, 8, 9], [10, 11, 12]]


numpy.tril(x,-1)  array([[ 0, 0, 0], (ceros por encima de la
[ 4, 0, 0], primera subdiagonal)
[ 7, 8, 0],
[10, 11, 12]])

numpy.triu(x,-1)  array([[ 1, 2, 3], (ceros por debajo de la


[ 4, 5, 6], primera subdiagonal)
[ 0, 8, 9],
[ 0, 0, 12]])

Matriz de Vandermonde
Dado un arreglo 1D, crea un arreglo 2D de Vandermonde, cuyas columnas
son potencias puntuales del arreglo 1D.
De forma predeterminada el arreglo es cuadrado, de potencias
decrecientes, pero opcionalmente esto se puede cambiar.
Ejemplo Vandermonde de 4 columnas, potencias crecientes:
numpy.vander([2,3,5],4,True)  array([[ 1, 2, 4, 8],
[ 1, 3, 9, 27],
[ 1, 5, 25, 125]])

Funciones de redondeo
x=[-4.9, -4.5, -4.1, -3.9, -3.5, -3.1, 3.1, 3.5, 3.9, 4.1, 4.5, 4.9]

Redondeo al entero mas cercano, opcionalmente especificando cantidad


de decimales:
numpy.around(x) 
array([-5., -4., -4., -4., -4., -3., 3., 4., 4., 4., 4., 5.])

Redondeo al entero mas cercano:


numpy.rint(x) 
array([-5., -4., -4., -4., -4., -3., 3., 4., 4., 4., 4., 5.])

Redondeo al entero mas cercano en dirección a 0


numpy.fix(x) 
array([-4., -4., -4., -3., -3., -3., 3., 3., 3., 4., 4., 4.])
Redondeo al entero menor mas cercano, o redondeo hacia abajo
numpy.floor(x) 
array([-5., -5., -5., -4., -4., -4., 3., 3., 3., 4., 4., 4.])

Redondeo al entero mayor mas cercano, o redondeo hacia arriba


numpy.ceil(x) 
array([-4., -4., -4., -3., -3., -3., 4., 4., 4., 5., 5., 5.])

Redondeo truncando decimales


numpy.trunc(x) 
array([-4., -4., -4., -3., -3., -3., 3., 3., 3., 4., 4., 4.])

Notar que con around y rint el redondeo del número a mitad de


intervalo entre dos enteros se redondea al entero par mas cercano.
Así 3.5 redondea a 4 y 4.5 también a 4. También se denomina redondeo
a par o bancario.
Si se redondeara siempre hacia arriba (o hacia abajo), el promedio de
un arreglo de números redondeados tendería a desplazarse hacia arriba
o hacia abajo. Si la ocurrencia de números terminados en 5 es
aleatoria, el redondeo hacia entero par tiende a mantener el
promedio.
Por ejemplo, sin redondeo a par, -0.5 redondearía a 0 y 0.5
redondearía a 1. El promedio de los redondeados sería 0.5 en lugar de
0.

Sumatoria de los elementos de un arreglo


x=[[1,2,3,5],[7,11,13,17]]
numpy.sum(x)  59 (sumatoria linealizada)
numpy.sum(x,0)  array([ 8, 13, 16, 22]) (sumatoria por columnas)

Sumatoria acumulada de los elementos de un arreglo


x=[[1,2,3,5],[7,11,13,17]]
numpy.cumsum(x)  array([ 1, 3, 6, 11, 18, 29, 42, 59],
dtype=int32)
numpy.cumsum(x,0)  array([[ 1, 2, 3, 5],
[ 8, 13, 16, 22]], dtype=int32)

Producto de los elementos de un arreglo


x=[[1,2,3,5],[7,11,13,17]]
numpy.prod(x)  510510 (producto linealizado)
numpy.prod(x,0)  array([ 7, 22, 39, 85]) (producto por columnas)

Producto acumulado de los elementos de un arreglo


x=[[1,2,3,5],[7,11,13,17]]
numpy.cumprod(x)  array([ 1, 2, 6, 30, 210, 2310, 30030, 510510],
dtype=int32)

Diferencias finitas de elementos de un arreglo


x=[[1,2,3,5],[7,11,13,17]]
numpy.diff(x)  array([[1, 1, 2], (por filas)
[4, 2, 4]])
numpy.diff(x,axis=0)  array([[ 6, 9, 10, 12]]) (por columnas)

Gradiente de un arreglo escalar


El resultado son tantos arreglos como dimensiones tenga el arreglo
escalar. Es posible especificar el intervalo de muestreo en cada
dirección. Predeterminado es 1 en todas las direcciones.

A=numpy.random.random_integers(-10,10,(5,5))
A  array([[ 6, 7, 0, -6, 8],
[ 0, 1, 6, -8, 4],
[ 0, -5, -4, 9, -1],
[ 5, -4, -9, 7, 7],
[ 6, 0, -1, 9, -6]])

Gradiente (derivada) de A en la dirección de columnas:


numpy.gradient(A)[0]
array([[ -6. , -6. , 6. , -2. , -4. ],
[ -3. , -6. , -2. , 7.5, -4.5],
[ 2.5, -2.5, -7.5, 7.5, 1.5],
[ 3. , 2.5, 1.5, 0. , -2.5],
[ 1. , 4. , 8. , 2. , -13. ]])

Integración trapezoidal
Calcula la integración numérica por regla trapezoidal. Se puede
especificar el intervalo de muestreo en cada dimensión, el cual es 1
de forma predeterminada.

A=numpy.random.random_integers(-10,10,(5,5))
A  array([[ 6, 7, 0, -6, 8],
[ 0, 1, 6, -8, 4],
[ 0, -5, -4, 9, -1],
[ 5, -4, -9, 7, 7],
[ 6, 0, -1, 9, -6]])

Integración por filas:


numpy.trapz(A) 
array([ 8. , 1. , -0.5, 0. , 8. ])

Producto escalar para arreglos 1D y 2D


Para matrices es el producto matricial, para vectores es suma de
productos elemento a elemento sin efectuar conjugada compleja.
A=[[1,2,3],[4,5,6],[7,8,9]]
x=[2,3,5]
y=[7,11,13]
numpy.dot(x,y)  112
numpy.dot(A,x)  array([23, 53, 83]) (producto por filas)
Productos internos: inner y vdot. Sólo para arreglos 1D.
inner obtiene un producto interno si los dos arreglos son reales;
sinó, es sólo la suma de productos elemento a elemento sin tomar
conjugada compleja.
vdot obtiene un verdadero producto interno, tomando conjugada al
primero de los vectores en el argumento.
numpy.vdot(z1,z2) equivale a numpy.inner(numpy.conj(z1),z2)
Tomando conjugada al segundo vector del argumento se obtiene la
conjugada del resultado que resulta con numpy.vdot

a=[2,3,5]; b=[7,11,13]
z1=list(map(complex,a,b))
z2=[complex(b[k],-a[k]) for k in range(len(a))]
z1  [(2+7j), (3+11j), (5+13j)]
z2  [(7-2j), (11-3j), (13-5j)]

numpy.inner(z1,z2)  (224+301j)
numpy.vdot(z1,z2)  -377j
numpy.inner(z1,z2)  (-301+224j)
numpy.vdot(z1,z2)  (377+0j)

Producto exterior o diádico de arreglos 1D: outer


outer equivale al producto "inner" de un vector columna por un vector
fila (no toma conjugada)
numpy.outer(z1,z2) 
array([[ 28. +45.j, 43. +71.j, 61. +81.j],
[ 43. +71.j, 66.+112.j, 94.+128.j],
[ 61. +81.j, 94.+128.j, 130.+144.j]])

Producto vectorial (vectores sólo de dimensión 2 o 3)


A=[[1,2,3],[4,5,6],[7,8,9]]
x=[2,3,5]
y=[7,11,13]
numpy.cross(x,y)  array([-16, 9, 1])
numpy.cross(A,y)  array([[ 1, 1, -1], (producto por filas)
[ 7, -8, 2],
[ 13, -17, 5]])

Convolución de arreglos 1D
Puede ser "full", "same" o "valid"
x=[2,3,5]
y=[7,11,13,17]
numpy.convolve(x,y)  array([ 14, 43, 94, 128, 116, 85]) ("full")

Correlación de arreglos 1D
Puede ser "valid", "same" o "full"
x=[2,3,5]
y=[7,11,13,17]
Correlación sólo con superposición completa de todos los elementos:
numpy.correlate(x,y)  array([146, 112]) (modo "valid")
numpy.correlate(x,x)  array([38]) (autocorrelación)

Correlación con la mayor longitud de los arreglos


numpy.correlate(x,y,"same")  array([ 77, 146, 112, 76])
numpy.correlate(x,x,"same")  array([21, 38, 21])

Correlación completa, incluyendo productos por cero


numpy.correlate(x,y,"full")  array([ 34, 77, 146, 112, 76, 35])
numpy.correlate(x,x,"full")  array([10, 21, 38, 21, 10])

Coeficiente de correlación. Covarianza normalizada.


Produce la matriz de correlación entre dos vectores, o entre
los vectores de un arreglo 2D.
A= [[-5, 2, -1], [3, -10, -10], [-10, -6, 4]]
x=[2,3,5]
y=[7,11,13]
numpy.corrcoef(x,y)  array([[ 1. , 0.92857143],
[ 0.92857143, 1. ]])
numpy.corrcoef(A)  array([[ 1. , -0.90419443, 0.35538624],
[-0.90419443, 1. , -0.72057669],
[ 0.35538624, -0.72057669, 1. ]])

Covarianza
Produce la matriz de covarianza entre dos vectores, o entre
los vectores de un arreglo 2D.
A= [[-5, 2, -1], [3, -10, -10], [-10, -6, 4]]
x=[2,3,5]
y=[7,11,13]
numpy.cov(x,y)  array([[ 2.33333333, 4.33333333],
[ 4.33333333, 9.33333333]])
numpy.cov(A)  array([[ 12.33333333, -23.83333333, 9. ],
[-23.83333333, 56.33333333, -39. ],
[ 9. , -39. , 52. ]])

Media
M=numpy.array([2,3,5,7,11,13,17,19,23]).reshape(3,3)

media de todo el arreglo:


numpy.average(M)  11.111111111111111

media de cada columna:


numpy.average(M,axis=0)  array([ 8.66666667, 11. , 13.66666667])

Mediana
M=numpy.array([2,3,5,7,11,13,17,19,23]).reshape(3,3)

mediana de todo el arreglo:


numpy.median(M)  11.0

mediana de cada fila:


numpy.median(M,axis=1)  array([ 3., 11., 19.])

Desviación típica
M=numpy.array([2,3,5,7,11,13,17,19,23]).reshape(3,3)

desviación típica de todo el arreglo:


numpy.std(M)  7.0307964531361664

Números complejos
z=[(1+2j),(3+4j)]
numpy.real(z)  array([ 1., 3.]) (parte real)
numpy.imag(z)  array([ 2., 4.]) (parte imaginaria)
numpy.abs(z)  array([ 2.23606798, 5. ]) (magnitud)
numpy.angle(z)  array([ 1.10714872, 0.92729522]) (fase, radianes)

Álgebra lineal
Solución de sistema de ecuaciones lineales compatibles
La matriz A debe ser cuadrada, no singular.
A=[[1,2,6],[1,1,2],[3,2,3]]
b=[1, 2, 3]
numpy.linalg.solve(A,b)  array([ -5., 15., -4.])

Solución de sistema de ecuaciones lineales incompatible, compatible


determinado y compatible indeterminado.
Ejemplo: ajuste de línea recta por mínimos cuadrados:
x=[2, 3, 5, 7, 11] (independiente)
y=[13, 17, 19, 23, 29] (dependiente)

Primero formar la matriz de Vandermonde del sistema:


M=numpy.vander(x,2,True)
ó con:
M=numpy.vstack([[1]*len(x),x]).T
M 
array([[ 1, 2],
[ 1, 3],
[ 1, 5],
[ 1, 7],
[ 1, 11]])
Después resolver el sistema usando la función lstsq:
numpy.linalg.lstsq(M,y)[0]  array([ 10.75 , 1.6875])

La constante es 10.75 y la pendiente de la recta es 1.6875

lstsq devuelve cuatro datos: arreglo de coeficientes de ajuste, norma


cuadrática del vector de errores, condición de la matriz y sus
valores singulares. En este ejemplo se tomó sólo el arreglo de los
coeficientes.

El vector de la variable dependiente (y) puede reemplazarse por una


matriz. En ese caso, la solución será también una matriz, donde cada
columna contiene los coeficientes de ajuste para cada vector columna
de y.

Valores y vectores propios de una matriz cuadrada


A=[[1,2,6], [1,1,2], [3,2,3]]

valores propios:
valprop=numpy.linalg.eig(A)[0] 
array([ 7.30761442, -2.36546502, 0.0578506 ])

Vectores propios derechos:


vecprop= numpy.linalg.eig(A)[1] 
array([[-0.70477152, -0.86588548, 0.36148084],
[-0.31352056, -0.0390854 , -0.90008492],
[-0.63639765, 0.49871301, 0.24326681]])
Cada fila contiene un vector propio

Sólo valores propios:


A=[[1,2,6], [1,1,2], [3,2,3]]
numpy.linalg.eigvals(A) 
array([ 7.30761442, -2.36546502, 0.0578506 ])

Valores propios y vectores propios de una matriz hermítica


Si la matriz es hermítica, es computacionalmente mas eficiente usar
las funciones numpy.linalg.eigh o numpy.linalg.eigvalsh en lugar de
las mas generales numpy.linalg.eig y numpy.linalg.vals:
A= [[11, 9, 17], [ 9, 9, 20], [17, 20, 49]] (matriz hermítica real)

numpy.linalg.eigh(A)[0] 
array([ 3.23858793e-03, 4.81064379e+00, 6.41861176e+01]

eigh devuelve un arreglo con los valores propios y la matriz de los


vectores propios. En este ejemplo sólo se tomó el arreglo de valores
propios.
Sólo valores propios de matriz hermítica.
A= [[11, 9, 17], [ 9, 9, 20], [17, 20, 49]] (matriz hermítica real)

numpy.linalg.eigvalsh(A) 
array([ 3.23858793e-03, 4.81064379e+00, 6.41861176e+01]

Descomposición USV o de valores singulares


A=[[1, 2, 3], [4, 5, 6]]

Valores singulares:
numpy.linalg.svd(A)[1]  array([ 9.508032 , 0.77286964])

La función svd devuelve la matriz unitaria U, el vector de valores


singulares S y la transpuesta hermítica de la matriz unitaria V,
tales que: U*S*V.H=A. En este ejemplo sólo se tomó el vector de
valores singulares S

Transformada de Fourier
http://docs.scipy.org/doc/numpy-1.10.0/reference/routines.fft.html

Sea g una función discreta con intervalo de muestreo constante, y G


su transformada de Fourier, la cual también es una función discreta
de intervalo constante.

Tranformadas en una dimensión:


numpy.fft.rfft(g) transformada de Fourier de función g real
numpy.fft.irfft(G) transformada inversa que produce función real g
numpy.fft.fft(g) transformada de Fourier de función real o compleja
numpy.fft.ifft(G) transformada inversa de Fourier real o compleja

Transformadas en dos dimensiones:


numpy.fft.rfft2(g) transformada de Fourier de función g real
numpy.fft.irfft2(G) transformada inversa que produce función real g
numpy.fft.fft2(g) transformada de Fourier de función real o
compleja
numpy.fft.ifft2(G) transformada inversa de Fourier real o compleja

Transformadas en n dimensiones:
numpy.fft.rfftn(g) transformada de Fourier de función g real
numpy.fft.irfftn(G) transformada inversa que produce función real g
numpy.fft.fftn(g) transformada de Fourier de función real o
compleja
numpy.fft.ifftn(G) transformada inversa de Fourier real o compleja

Las transformadas de funciones reales solo producen la parte


correspondiente a frecuencias positivas, porque la función de la
transformada es hermítica.
En general, si g es real, entonces G es compleja.
Para obtener el espectro de amplitud usar:
Amplitud=numpy.abs(G)

y el espectro de fase:
Fase=numpy.angle(G)

Creadoras de abcisas en frecuencia


Estas funciones son útiles para crear arreglos de las abcisas
(frecuencia, número de onda) con el fin de graficar en el dominio de
la transformada, por ejemplo el espectro de amplitud, o fase.
Las siguientes llevan el prefijo numpy.fft. :

rfftfreq(n,d=dt) obtiene arreglo de abcisas para transformada de


función real 1D. Se usan con transformadas rfft e
irfft. Sólo produce la parte de frecuencias no
negativas.
n es el número de puntos y dt el intervalo de
muestreo, el cual es igual a 1 si no se
especifica.
fftfreq(n,d=dt) obtiene arreglo de abcisas para transformada de
función real o compleja 1D, con las frecuencias de
Nyquist en el centro del arreglo.
n es el número de puntos y dt el intervalo de
muestreo, el cual es igual a 1 si no se
especifica.
fftshift(f) ordena las frecuencias de menor a mayor en el
arreglo de frecuencias producido por fftfreq, de
tal forma que la frecuencia correspondiente a f=0
quede en el centro del arreglo, la frecuencia de
Nyquist negativa al comienzo del arreglo y la
frecuencia de Nyquist positiva al final del
arreglo.
ifftshift(f) hace lo inverso de fftshift, de tal forma que la
frecuencia correspondiente a f=0 queda al inicio
del arreglo y las frecuencias de Nyquist positiva
y negativa en el centro del mismo.

Ejemplos:
g=[2, 3, 5, 7, 11, 13] (función real discreta)

Transformada de Fourier de función real


G=numpy.fft.rfft(g)
G  array([ 41. +0.j , -5.+13.85640646j, -7. +3.46410162j, -5. +0.j
])

Sólo produce la parte del espectro correspondiente a las frecuencias


no negativas.
Si se necesitase la parte de las frecuencias negativas, se puede
obtener con:
G[-2:0:-1].conjugate()  array([ -7. -3.46410162j, -5.-13.85640646j
])

Transformada inversa, que recupera la función real


numpy.fft.irfft(G)  array([ 2., 3., 5., 7., 11., 13.])

Transformada usando fft


g=[2, 3, 5, 7, 11, 13]
G=numpy.fft.fft(g)
G 
array([ 41. +0.00000000e+00j, -5. +1.38564065e+01j, -7.
+3.46410162e+00j, -5. +7.10542736e-15j, -7. -3.46410162e+00j, -5.
-1.38564065e+01j])

En este arreglo comienza con el valor del espectro correspondiente a


f=0 (41) y el valor correspondiente a la frecuencia de Nyquist
negativa lo sitúa en la mitad (muestra 4, valor -5). Notar la
simetría hermítica en torno a -5

Transformada inversa
numpy.fft.ifft(G) 
array([ 2. +0.00000000e+00j, 3. -2.36847579e-15j, 5. +5.36588719e-
15j, 7. -5.92118946e-16j, 11. -1.81317351e-15j, 13. -5.92118946e-
16j])
Debería dar una función real. Aquí la parte imaginaria es causada por
imprecisión numérica en los cálculos, siendo el error del orden de
10-15

Arreglo de frecuencias para función real


f=numpy.fft.rfftfreq(6,d=2) (6 muestras, intervalo muestreo 2)
f  array([ 0. , 0.08333333, 0.16666667, 0.25 ])
La frecuencia de Nyquist positiva es 0.25 ( 1/(2*2) )

Arreglo de frecuencias para función real o compleja


f=numpy.fft.fftfreq(6,d=2) (6 muestras, intervalo muestreo 2)
f  array([ 0. , 0.08333333, 0.16666667, -0.25 , -0.16666667,
-0.08333333])
La frecuencia de Nyquist negativa está situada en el centro del
arreglo

Ordenamiento del arreglo de frecuencias de función real o compleja


numpy.fft.fftshift(f)
 array([-0.25 , -0.16666667, -0.08333333, 0. , 0.08333333,
0.16666667])
Ahora las frecuencias están ordenadas de menor a mayor, con la
frecuencia f=0 en el centro del arreglo.
Transformada de Hilbert

Sea g una función discreta con intervalo de muestreo constante, y h


su transformada de Hilbert, la cual también es una función discreta
de intervalo constante.

import scipy.signal as sse

g=[2, 3, 5, 7, 11, 13]


A=sse.hilbert(g)
A 
array([ 2.+4.63367665j, 3.-2.42784414j, 5.-1.15437028j,
7.-3.83852875j, 11.+2.78706653j])

A es la señal analítica, una función compleja cuya parte real es


igual a la función original g, y cuya parte imaginaria es su
transformada de Hilbert h, es decir: A=g+hj

Para obtener la transformada de Hilbert directamente, se puede hacer


h=sse.hilbert(g).imag
h 
array([ 4.63367665, -2.42784414, -1.15437028, -3.83852875,
2.78706653])

La denominada función envolvente o "amplitud instantánea" se puede


obtener con:
Amplitud=abs(A)
Amplitud 
array([ 5.04687619, 3.85932989, 5.13152714, 7.98337666, 11.3475874 ])

La "fase instantánea" (en radianes) con:


Fase=numpy.angle(A)
Fase 
array([ 1.1633296 , -0.68037475, -0.22689837, -0.50158418,
0.24814761])

La "frecuencia instantánea" (sin filtrar y con dt=1) con:


Frecuencia=numpy.gradient(numpy.angle(A))
Frecuencia 
array([-1.84370435, -0.69511398, 0.08939529, 0.23752299, 0.74973179])
GRÁFICOS

Existen varios módulos para graficación en Python. El mas conocido es


Matplotlib, que contiene submódulos para graficación 2D o 3D.
Otros menos conocidos son: Visvis, PyQtgraph, Mayavi, Veusz, Chaco,
PyQwt, GUIQwt, Ggplot, Bokeh, Vega, Vincent, Gnuplot.py, MathGL,
DiaGrabber, Gplot, Seaborn (para Estadística)
Sin embargo, la mayoría de ellos usan a su vez Matplotlib.

Página principal de Matplotlib:


http://matplotlib.org/

Ejemplos:
http://matplotlib.org/examples/
http://matplotlib.org/users/image_tutorial.html
http://matplotlib.org/examples/images_contours_and_fields/interpolati
on_methods.html

Para gráficos 3D se pueden usar los módulos de Matplotlib, pero


quizás es mejor Mayavi:
http://docs.enthought.com/mayavi/mayavi/index.html

Matplotlib puede usarse en dos formas principales: una simple con una
sintaxis muy parecida a la de los gráficos en Octave/Matlab y otra en
un marco de programación orientada a objetos, no tan sencilla pero
mucho mas poderosa.

En este sentido, es conveniente tener en cuenta que cada función de


graficación puede devolver un tipo de objeto o propiedad.
Resulta útil determinar el tipo de objeto y sus métodos y propiedades
asociadas, tanto para saber cuales son aplicables, como para buscar
información sobre ellos.

Un ejemplo con la función figure de matplotlib.pyplot:


import matplotlib.pyplot as plt
type(plt.figure())  matplotlib.figure.Figure (tipo de objeto)
dir(plt.figure())  (lista de 198 métodos y propiedades (1.5.0))

['__class__',
'__delattr__',
'__dict__',
'__dir__',
.........
'update',
'update_from',
'waitforbuttonpress',
'zorder']
Para la mayoría de gráficos, es suficiente el modo simple con las
funciones del submódulo pyplot:

import matplotlib.pyplot as plt

Matplotlib tiene un conjunto de parámetros predeterminados para


graficación, los cuales se guardan en un diccionario, cuyo contenido
se puede ver con:
plt.rcParams

Se ilustrará el uso de algunas funciones de Matplotlib con programas:

# Ejemplos de graficación 2D
# Gráficos cartesianos

# Importa el paquete de funciones numéricas numpy


import numpy

# Importa el paquete de funciones gráficas matplotlib.pyplot


import matplotlib.pyplot as plt

# Activa modo interactivo para que muestre los gráficos automáticamente


plt.ion()

# Cierra gráficos previos, si existen


plt.close("all")

# arreglos de abcisas y ordenadas de función seno cardinal


x=numpy.arange(-5,5,0.1)
y=numpy.sinc(x)

# FIGURA 1
# Crea figura 1
plt.figure(1)

# Dibuja el gráfico simple con valores predeterminados


plt.plot(x,y)

# FIGURA 2
# Produce una segunda curva, derivada de la primera
yd=numpy.gradient(y)*5

# Crea figura 2
plt.figure(2)

# Obtiene identificador de objeto axes


ax=plt.gca()
# Pone color de fondo en el objeto axes
ax.set_axis_bgcolor((0.75,0.5,0.25))

# Grafica curva de la función seno cardinal (sinc), especificando


# muchos parámetros de diversas formas
curva1,=plt.plot(x,y,"ro-",label='sinc',linewidth=4,color=(0,0,1),markersiz
e=6,markerfacecolor=(1,0,0),markeredgecolor="g",markeredgewidth=2)

# Asegura superposición de gráficos sucesivos en una misma ventana


plt.hold(True)

# Grafica curva de derivada de la función seno cardinal,


# especificando muchos parámetros de diversas formas
curva2, = plt.plot(x,yd,label="derivada", linestyle="--", linewidth=3,
color="c", marker="x", markersize=7, markeredgecolor="m",
markeredgewidth=3, alpha=0.5)

# Pone las leyendas de las curvas


plt.legend(handles=[curva1,curva2])

# Especifica los límites del eje de abcisas


plt.xlim([-5.5,5.5])

# Especifica los límites del eje de las ordenadas


plt.ylim([-0.8,1.2])

# Etiqueta el eje de las abcisas


plt.xlabel('abcisas'+ r' ($\alpha$)',fontsize=14,color=(0.12,0.25,0.50))

# Etiqueta el eje de las ordenadas


plt.ylabel("ordenadas",fontsize=14,color=(0.12,0.25,0.50))

# Pone un título al gráfico


plt.title("SENO CARDINAL Y DERIVADA",fontsize=24,
color="blue",weight="bold",family="Bitstream Vera Serif")

# Pone malla de coordenadas


plt.grid(color="red")

Comentarios

import matplotlib.pyplot as plt


Se comienza importando el módulo de graficación matplotlib.pyplot, el
cual proporciona el conjunto simple de funciones, con sintaxis
similar a la de las funciones gráficas de Matlab/Octave.
En el nombre "matplotlib", "mat" se refiere a Matlab, porque
originalmente estas funciones se crearon para facilitar el paso de
Matlab a Python.
plt.ion()
Necesario para que muestre los gráficos en modo interactivo, como en
el shell Ipython.

plt.close("all")
Preventivamente cierra gráficos para evitar la posibilidad de
graficar sobre gráficos preexistentes.

x=numpy.arange(-5,5,0.1)
y=numpy.sinc(x)
Crea un arreglo de abcisas (x) y un arreglo de ordenadas (y)
obtenidas con la función seno cardinal. Se representará graficamente
esta función.

plt.figure(1)
Crea la ventana de la figura 1. Esta instrucción no es necesaria si
solo se fuese a graficar una figura.

plt.plot(x,y)
Grafica la figura simplemente con los datos de abcisas y ordenadas.
Automáticamente elije los límites del gráfico y agrega escalas a
ambos ejes.
Figura 1 Gráfico cartesiano resultante de graficación simple:
plt.plot(x,y) con los parámetros predeterminados.

plt.figure(2)
Crea nueva ventana gráfica o figura, identificada con número 2.
La identificación de figuras no es necesaria, excepto cuando se
tienen dos o mas figuras y el foco de atención del programa puede
cambiar alternativamente entre ellas.

ax=plt.gca()
Duplica en ax un objeto "axes" o escena en la figura 2. El objeto
axes es un widget gráfico que existe en un espacio de coordenadas (de
allí la clase "axes"). En una figura puede haber mas de un axes.

ax.set_axis_bgcolor((0.75,0.5,0.25))
Establece el color de fondo para la escena. El color es indicado
mediante una tupla de 3 o 4 números números, correspondientes a los
colores rojo, verde, azul y opcionalmente opacidad, en ese orden. Los
valores están normalizados al intervalo [0,1], e indican la
intensidad de cada color y la opacidad.
Un color con intensidad (0,0,0) corresponde a negro; (1,1,1) es
blanco intenso; (0.5,0.5,0.5) es gris, (1,0,0) es rojo intenso, etc.
El color es transparente si la opacidad es 0, y totalmente opaco si
es 1. Por ejemplo (1.0, 1.0, 0.0, 0.5) es amarillo semitransparente.
Si no se especifica, la opacidad es 1.0 de forma predeterminada.
Otra forma de indicar colores es mediante el nombre del color, según
la norma html:
http://www.w3schools.com/html/html_colornames.asp

Por ejemplo: "black", "white", "gray", "red", "beige",


"DarkGoldenRod".
También mediante un solo caracter de la colección de 8 colores de
Matlab/Octave indicados con: "w", "k", "r", "g", "b", "y", "c" y "m"
correspondientes a: blanco, negro, rojo, verde, azul, amarillo, cián
y fucsia
Una cuarta forma es utilizar el código de colores html en formato
hexadecimal; por ejemplo: "#000000" corresponde a negro,
"#FFFFFF" es blanco brillante, "#FA8072" es salmón. Sin embargo,
todavía no hay forma de especificar la opacidad con este código.

curva1,=plt.plot(x,y,"ro-",label='sinc',linewidth=4,color=(0,0,1),markersiz
e=6,markerfacecolor=(1,0,0),markeredgecolor="g",markeredgewidth=2)
Grafica ordenadas (y) contra abcisas (x), con muchas opciones.
curva1 es el objeto gráfico producido por plt.plot. Este objeto tiene
numerosos métodos y por eso se asigna al duplicado o alias "curva1".
Notar que debe ponerse una coma después de curva1.
"ro-" significa: color de curva: rojo (r), símbolo marcador: círculos
(o), estilo de línea: contínua (-).
label='sinc': etiqueta identificadora de esta curva. Se utilizará
posteriormente para identificar las curvas en el gráfico.
linewidth=4: grosor de la línea en puntos
color=(0,0,1): color de la curva, usando una tupla de 3 números. En
este ejemplo indica azul intenso. Notar que el color de curva había
sido establecido previamente en rojo, pero esta opción la cambia a
azul.
markersize=6: tamaño de símbolos marcadores en puntos
markerfacecolor=(1,0,0): color de relleno de los símbolos marcadores
especificado con una tupla de 3 números. En este caso, color rojo
intenso.
markeredgecolor="g": color del borde de los símbolos marcadores.
Verde, especificado en este ejemplo mediante un solo carácter.
markeredgewidth=2: ancho del borde de los marcadores en puntos.
Colección de símbolos: http://matplotlib.org/api/markers_api.html
Estilo de líneas: http://matplotlib.org/api/lines_api.html
Colores: http://matplotlib.org/api/colors_api.html

plt.hold(True)
Asegura superposición de gráficos sucesivos en una misma ventana,
porque pudiera ocurrir que hubiese sido desactivado previamente.

curva2, = plt.plot(x,yd,label="derivada", linestyle="--", linewidth=3,


color="c", marker="x", markersize=7, markeredgecolor="m",
markeredgewidth=3, alpha=0.5)

Grafica una segunda curva en la misma ventana de la figura 2,


superponiéndose.
El estilo de línea es punteado (--), el color es cian(c), los
símbolos marcadores son x, el color de los marcadores es fucsia(m), y
todos los elementos gráficos de esta curva son semitransparentes:
alpha=0.5 . Transparencia total: alpha=0 y opacidad total: alpha=1

plt.legend(handles=[curva1,curva2])
Grafica las etiquetas identificadoras de cada curva. En este ejemplo
se indica el orden de presentación con una lista. El texto de la
etiqueta es el mismo utilizado en las opciones "label" de plot; sin
embargo, es posible cambiarlos por otros especificándolos en una
lista como otro argumento de legend. También se puede especificar su
ubicación en el gráfico.

plt.xlim([-5.5,5.5])
plt.ylim([-0.8,1.2])
Especifica los límites de la escala del eje x y del eje y. Si no se
especificasen, serían elegidos por la función plot.

plt.xlabel('abcisas'+ r' ($\alpha$)',fontsize=14,color=(0.12,0.25,0.50))


plt.ylabel("ordenadas",fontsize=14,color=(0.12,0.25,0.50))
Pone etiqueta al eje de las abcisas y al de ordenadas. En las abcisas
concatena la palabra 'abcisas' con la cadena ' ($\alpha$)'.
La r antes de las comillas de la segunda cadena significa "raw" o
literal, con el fin de que se pueda interpretar correctamente el
formato de texto LaTeX encerrado entre signos dólar ($).
$\alpha$ significa que imprima la letra griega alfa usando tipografía
LaTeX.
fontsize=14 indica el tamaño de letra en puntos
color=(0.12,0.25,0.50) indica que el color de letra con una tupla

plt.title("SENO CARDINAL Y DERIVADA",fontsize=24,


color="blue",weight="bold",family="Bitstream Vera Serif")
Pone un título al gráfico, de color azul y resaltado (bold).
Especifica también el tipo de letra: Bitstream Vera Serif

plt.grid(color="red")
Superpone una malla de líneas de coordenadas de color rojo
en el gráfico
Figura 2. Gráfico cartesiano de dos curvas realizado con plot y otras
funciones de matplotlib.pyplot, especificando algunos parámetros,
tales como tipo de línea, símbolos, colores, etiquetas, título,
límites de ejes coordenados.
# Ejemplos de graficación 2D
# Gráfico cartesiano cruzado
# Curvas de un conjunto de puntos abcisas y otro ordenadas
# Trata de simular los puntos de un gráfico densidad-velocidad P de rocas y
# sedimentos usando la fórmula empírica de Gardner

# Importa el paquete de funciones numéricas numpy


import numpy

# Importa las funciones de interpolación de scipy


import scipy.interpolate as itp

# Importa el módulo de funciones gráficas matplotlib.pyplot


import matplotlib.pyplot as plt

# Activa modo interactivo para que muestre los gráficos automáticamente


plt.ion()

# Cierra gráficos previos, si existen


plt.close("all")

# arreglos de abcisas y ordenadas de función seno cardinal


np=100 # número de puntos en el gráfico
velmen=1500. # velocidad menor (m/s)
velmay=7000. # velocidad mayor
dvel=1. # intervalo de velocidades

p=1.0 # factor de potencia


q=0.0008 # factor de atenuación exponencial
a=0.1 # factor de amplitud

# rango de velocidades
t=numpy.arange(velmen,velmay,dvel)

# calcula velocidades según esta distribución estadística


# El máximo está en: p/q y el punto de inflexión en: (p+sqrt(p))/q.
(Bronshtein et al. 2005, p. 74)
f=0.1*t**p*numpy.exp(-q*t)

# función de distribución acumulada


s=f.cumsum()

# normaliza al intervalo [0,1]


s=(s-s[0])/(s[-1]-s[0])

# obtiene la función interpoladora (funin) con interpolación lineal


funin=itp.interp1d(s,t)
# puntos aleatorios de distribución uniforme en [0,1)
sa=numpy.random.random(np)

# obtiene las velocidades interpoladas con la función interpoladora en los


puntos aleatorios en [0,1)
v=funin(sa)

# arreglo de factor multiplicando en la función de Gardner


a=0.31+0.002*numpy.random.randn(np)

# arreglo de exponentes en la función de Gardner


m=0.25+numpy.random.randn(np)*0.005

# calcula densidades usando función de Gardner


den=a*v**m

# FIGURA 1
# Crea figura 1
plt.figure(1)

# Obtiene identificador axes


scn=plt.gca()

# Pone color de fondo en la figura


scn.set_axis_bgcolor((0.55,0.27,0.14))
#scn.set_axis_bgcolor("#8B4513")

# Grafica puntos dispersos, especificando parámetros de diversas formas


plt.plot(den,v,"^",linestyle="None",markersize=6,markerfacecolor=(1,1,0),ma
rkeredgecolor="g",markeredgewidth=2)

# Especifica los límites del eje de abcisas


plt.xlim([1.0,3.5])

# Especifica los límites del eje de las ordenadas


plt.ylim([0.0,7500.0])

# Etiqueta el eje de las abcisas


plt.xlabel(r'$\mathrm{\rho \ (g/cm^3)}$',fontsize=18,family="Bitstream Vera
Sans",color=(0.12,0.25,0.50))

# Etiqueta el eje de las ordenadas


plt.ylabel(r'$\mathrm{Velocidad \
(m/s)}$',fontsize=18,color=(0.12,0.25,0.50))

# Pone un título al gráfico


plt.title("NAFE-DRAKE SIMULADO",fontsize=18,
color="blue",weight="bold",family="Bitstream Vera Sans")
# Pone malla de coordenadas
plt.grid(color="white")

Comentarios

import numpy
Importa las funciones de arreglos numéricos

import scipy.interpolate as itp


Importa funciones de interpolación numérica del módulo scipy. Se le
asigna el alias "itp"

import matplotlib.pyplot as plt


Importa funciones de graficación simples. Se le asigna el alias "plt"

plt.ion()

plt.close("all")

np=100 # número de puntos en el gráfico


velmen=1500. # velocidad menor (m/s)
velmay=7000. # velocidad mayor
dvel=1. # intervalo de velocidades
p=1.0 # factor de potencia
q=0.0008 # factor de atenuación exponencial
a=0.1 # factor de amplitud
Inicializa un conjunto de variables que se utilizarán en los cálculos

t=numpy.arange(velmen,velmay,dvel)
Obtiene un rango de velocidades con la función "numpy.arange". Esta
función puede obtener rangos con números flotantes o enteros, a
diferencia de la básica de Python "range" que solo acepta enteros.

f=0.1*t**p*numpy.exp(-q*t)
Utiliza funciones Numpy que aceptan como argumento sucesiones de
números; es decir, se está usando la capacidad vectorial de Numpy.

s=f.cumsum()
Calcula una distribución acumulativa s, utilizando el método "cumsum"
del arreglo Numpy f creado

s=(s-s[0])/(s[-1]-s[0])
Realiza una normalización de los valores del arreglo s para que todos
estén comprendidos entre 0.0 y 1.0

funin=itp.interp1d(s,t)
Obtiene un objeto que representa una función de interpolación en 1D.
Utiliza la función interp1d del paquete Scipy.
El método de interpolación predeterminado es lineal; o sea, interpola
con rectas entre puntos sucesivos.

sa=numpy.random.random(np)
Utiliza la función random del módulo random del paquete Numpy para
obtener un arreglo sa de números aleatorios de distribución uniforme
en el intervalo [0,1)

v=funin(sa)
Utiliza la función interpoladora para obtener valores de velocidad
interpolados, para los valores aleatorios del arreglo sa

a=0.31+0.002*numpy.random.randn(np)
Utiliza la función randn para generar un arreglo de números
aleatorios de distribución normal, con media 0 y desviación típica 1.
Al multiplicarlos por 0.002, la desviación típica será ese número.
Este arreglo corresponde a valores de la constante que multiplica en
la relación densidad-velocidad de Gardner

m=0.25+numpy.random.randn(np)*0.005
Lo mismo para el exponente en la relación densidad-velocidad de
Gardner, pero con desviación típica 0.005

den=a*v**m
Calcula el arreglo de densidades con la fórmula de Gardner

plt.figure(1)
Crea la ventana de figura 1 (figura 3 de este instructivo)

scn=plt.gca()
Obtiene un alias para un objeto axes dentro de la primera figura.

scn.set_axis_bgcolor((0.55,0.27,0.14))
Otra forma de establecer el color de fondo de objetos axes, es con el
método set_axis_bgcolor.
El color indicado con la tupla (0.55,0.27,0.14) es equivalente a
especificarlo con la cadena: "#8B4512" del código html hexadecimal.

plt.plot(den,v,"^",linestyle="None",markersize=6,markerfacecolor=(1,1,0),ma
rkeredgecolor="g",markeredgewidth=2)
den, v son las sucesiones de coordenadas de los datos de densidad y
velocidad.
"^" indica que el símbolo marcador es un triángulo "derecho".
linestyle="None" se utiliza para evitar que los puntos sean unidos
mediante segmentos de recta y de esta forma lograr un gráfico de
puntos dispersos. Lo mismo se logra usando la función scatter.
markersize=6 indica tamaño del símbolo marcador en puntos
markerfacecolor=(1,1,0) indica color amarillo de relleno del marcador
markeredgecolor="g" indica borde de marcador de color verde
markeredgewidth=2 indica ancho de borde de marcador igual a 2 puntos

plt.xlim([1.0,3.5])
plt.ylim([0.0,7500.0])

plt.xlabel(r'$\mathrm{\rho \ (g/cm^3)}$',fontsize=18,
color=(0.12,0.25,0.50))
Pone la identificación del eje x.
r'$\mathrm{\rho \ (g/cm^3)}$':
la r antes de la comilla indica modo literal, para que Python
interprete correctamente la cadena entre comillas
El texto entre signos dólar $ contiene instrucciones LaTeX:
\mathrm indica que el texto entre llaves debe mostrarse con tipo de
letra Roman
\rho es la letra griega ro
\ seguido de espacio en blanco, inserta espacio en blanco
^3 supraíndice 3
fontsize indica el tamaño de letra, y color el color de letra

plt.ylabel(r'$\mathrm{Velocidad \
(m/s)}$',fontsize=18,color=(0.12,0.25,0.50))
Igual comentario que xlabel, para el eje y

plt.title("NAFE-DRAKE SIMULADO",fontsize=18,
color="blue",weight="bold",family="Bitstream Vera Sans")

plt.grid(color="white")
Figura 3. Gráfico de puntos dispersos simulando un gráfico densidad-
velocidad de Nafe-Drake. Se utilizó la función plot de Pyplot, y se
anuló la unión de puntos mediante rectas estableciendo la propiedad
linestyle="None". El mismo resultado se puede lograr con la función
scatter de Pyplot.
# Ejemplo de gráfico bilogarítmico
# Grafica las resistividades aparentes de un sondeo eléctrico vertical
# Schlumberger

# importa el paquete numérico Numpy


import numpy

# importa las funciones de interpolación del paquete Scipy, con alias itp
import scipy.interpolate as itp

# importa las funciones de graficación sencillas del paquete matplotlib con


# alias plt
import matplotlib.pyplot as plt

# Activa modo interactivo para que muestre los gráficos automáticamente


plt.ion()

# cierre preventivo de todos los gráficos previos


plt.close("all")

# Datos de sondeo Schlumberger


# Distancias AB/2 (m)
ab2=[1, 1.39, 1.93, 2.68, 3.73, 5.18, 7.2, 10, 13.9, 19.3, 26.8, 37.3,
51.8, 72, 100, 139, 193, 268, 373, 518, 720, 1000, 1390]

# Resistividades aparentes medidas (ohm.m)


roa=[85.2, 69.99, 54.99, 25.97, 11.99, 5.81, 4.39, 4.05, 4.08, 4.25, 4.6,
5.52, 7.04, 9.48, 13.15, 17.73, 25.28, 34.43, 48.23, 65.63, 90.04, 118.14,
168.39]

# FIGURA 1
# Crea figura 1
plt.figure(1)

# Obtiene alias para un objeto axes de esta figura


scn=plt.gca()

# Pone color de fondo en la escena


scn.set_axis_bgcolor((0.10,0.20,0.30))

# Grafica curva de resistividades aparentes Schlumberger


plt.loglog(ab2,roa,"hg-", markersize=8, markerfacecolor=(1,0,0),
markeredgecolor="g", markeredgewidth=2)

# Especifica los límites del eje de abcisas


# Obtiene tupla de límites del eje de abcisas
xlm=plt.xlim()
# Cambia el límite inferior del eje a 0.1
plt.xlim( (0.1, xlm[1]) )

# Etiqueta el eje de las abcisas


plt.xlabel(r'$\mathrm{Distancia\ AB/2\ (m)}$',fontsize=18,color="black")

# Etiqueta el eje de las ordenadas


plt.ylabel(r'$\mathrm{Resistividad\ aparente\
(\Omega.m)}$',fontsize=18,color="black")

# Pone un título al gráfico


plt.title("SONDEO ELÉCTRICO SCHLUMBERGER",fontsize=18,
color="blue",weight="bold",family="Bitstream Vera Serif")

# Pone malla de coordenadas


plt.grid(color="yellow")

Comentarios nuevos

ab2=[1, 1.39, 1.93, 2.68, 3.73, 5.18, 7.2, 10, 13.9, 19.3, 26.8, 37.3,
51.8, 72, 100, 139, 193, 268, 373, 518, 720, 1000, 1390]

roa=[85.2, 69.99, 54.99, 25.97, 11.99, 5.81, 4.39, 4.05, 4.08, 4.25, 4.6,
5.52, 7.04, 9.48, 13.15, 17.73, 25.28, 34.43, 48.23, 65.63, 90.04, 118.14,
168.39]
Define directamente dos listas de datos, una de distancias AB/2 (ab2)
y otra de resistividades aparentes medidas (roa)

plt.loglog(ab2,roa,"hg-", markersize=8, markerfacecolor=(1,0,0),


markeredgecolor="g", markeredgewidth=2)
Gráfico bilogarítmico con la función loglog (figura 4)
"hg-" significa: utilizar hexágonos como símbolos marcadores (h),
curva de color verde (g), línea continua (-)

xlm=plt.xlim()
En este ejemplo, la función xlim, sin argumentos, devuelve los
límites del eje x y los guarda en la lista xlm

plt.xlim( (0.1, xlm[1]) )


En esta instrucción se utiliza la función xlim para cambiar el límite
inferior del eje x a 0.1 . El límite superior se copia del guardado
en la lista xlm

plt.ylabel(r'$\mathrm{Resistividad\ aparente\
(\Omega.m)}$',fontsize=18,color="black")
En la etiqueta del eje y, la letra griega omega mayúscula se indica
mediante \Omega; es decir: comenzando el nombre de la letra con una
mayúscula.

Figura 4. Ejemplo de gráfico bilogarítmico realizado con la función


loglog de Pyplot.
# Ejemplos de graficación 2D
# Gráficos polares

# Importa el paquete de funciones numéricas numpy


import numpy

# Importa el módulo de funciones gráficas matplotlib.pyplot


import matplotlib.pyplot as plt

# Activa modo interactivo para que muestre los gráficos automáticamente


plt.ion()

# Cierra gráficos previos, si existen


plt.close("all")

# arreglos de abcisas y ordenadas de función seno cardinal


x=numpy.arange(-3,3.1,0.1)
y=numpy.sinc(x)

# FIGURA 1

# Crea figura 1
plt.figure(1)

# Establece tipo de gráfico y color de fondo en el lienzo


# Sobre este tema leer comentario del ejemplo en:
#http://matplotlib.org/1.2.1/examples/pylab_examples/polar_demo.html

plt.axes(polar=True,axisbg=(0.75,0.5,0.25))

# otra forma:
#plt.axes(projection="polar",axisbg=(0.75,0.5,0.25))

# Grafica curva de la función seno cardinal, especificando


# algunos parámetros
# Considera x el ángulo en radianes y y la magnitud
# NOTA: en la función polar, la parte de magnitud debe ser no negativa
plt.plot(x,abs(y),"ro-", label='sincrónica', linewidth=4, color=(0,0,1),
markersize=3)

# otra forma:
# plt.gca(projection="polar",axisbg="#2F4F4F")
# plt.plot(x,abs(y))

# otra forma:
# plt.polar(x,abs(y))

# Pone un título al gráfico


plt.title("SENO CARDINAL EN POLARES",fontsize=24,
color="blue",weight="bold",family="Bitstream Vera Serif")

# Pone malla de coordenadas


plt.grid(color="white")

# FIGURA 2
# Curva polar en gráfico cartesiano
plt.figure(2)

# Pone color de fondo en la escena utilizando codigo hexadecimal según


norma html
plt.gca(axisbg="#191970")

# Gráfico cartesiano, pero la curva es polar debido a la transformación de


coordenadas
plt.plot(y*numpy.cos(x),y*numpy.sin(x),linestyle=":",color="y",linewidth="3
",marker="*",markerfacecolor="w",markersize=12)

# Pone un título al gráfico


plt.title("SENO CARDINAL EN POLARES",fontsize=24,
color="green",weight="bold",family="Bitstream Vera Serif")

# Pone malla de coordenadas de color amarillo


plt.grid(color="y")

Comentarios nuevos

plt.axes(polar=True,axisbg=(0.75,0.5,0.25))
Aplica la opción de gráfico polar al objeto axes de esta figura.
También establece el color de fondo.

plt.plot(x,abs(y),"ro-", label='sincrónica', linewidth=4, color=(0,0,1),


markersize=3)
Grafica el gráfico polar (figura 5). En los gráficos polares
interpreta que x representa ángulos (variable independiente),
mientras que y representa magnitudes radiales.
Notar que las magnitudes radiales deben ser no negativas, por eso se
toma el valor absoluto: abs(y)
Una alternativa a esta forma, es utilizar directamente la función
polar, con los mismos argumentos. En ese caso no es necesario una
instrucción previa para indicar a axes la proyección polar.

plt.plot(y*numpy.cos(x),y*numpy.sin(x),linestyle=":",color="y",linewidth="3
",marker="*",markerfacecolor="w",markersize=12)
En la figura 6, se grafica la misma curva: el gráfico es cartesiano,
pero la curva es polar.
Esto se logra haciendo la transformación de coordenadas polares a
cartesianas: se multiplica la magnitud por el coseno y el seno del
ángulo para obtener las coordenadas cartesianas.
El marcador indicado por el asterisco (*) será graficado como una
estrella. El estilo de línea selecionado es punteado (:)

Figura 5. Gráfico del seno cardinal en coordenadas polares,


utilizando un objeto axes con proyección polar.
Figura 6. Gráfica del seno cardinal en coordenadas polares sobre un
gráfico cartesiano.
Se utiliza la función plot de Pyplot, pero previamente las
coordenadas polares de los puntos se transformaron a cartesianas.
# Ejemplo de gráfico de histograma, diagrama de caja y diagrama de violín

# Importa el paquete de funciones numéricas numpy#


import numpy

# Importa las funciones de interpolación del paquete Scipy con alias itp
import scipy.interpolate as itp

# Importa el módulo de funciones de graficación sencillas de matplotlib con


alias plt
import matplotlib.pyplot as plt

# Importa la función LineCollection del módulo collections de matplotlib


from matplotlib.collections import LineCollection

# Activa modo interactivo para que muestre los gráficos automáticamente


plt.ion()

# Cierre preventivo de todos los gráficos abiertos


plt.close("all")

# Las siguientes instrucciones tienen como finalidad


# obtener una distribución de velocidades parecida a la
# real en medios sedimentarios saturados y basamento
velmen=1500. # menor velocidad (m/s)
velmay=7000. # mayor velocidad
dvel=1. # intervalo de velocidades

p=1.0 # factor de potencia


q=0.0008 # factor de atenuación
a=0.1 # factor de amplitud

# rango de velocidades
t=numpy.arange(velmen,velmay,dvel)

# calcula velocidades
f=0.1*t**p*numpy.exp(-q*t)

# función acumulativa
# Observación: la función de velocidad utilizada tiene integral elemental.
# (Bronshtein et al. (2005), p. 1051, fórmulas 447-450)
# Sin embargo, si se reemplaza por otra función, puede que no tenga
# integral elemental.
s=f.cumsum()

# normaliza a [0,1]
s=(s-s[0])/(s[-1]-s[0])
# obtiene la función interpoladora (funin) con interpolación lineal
funin=itp.interp1d(s,t)

# números aleatorios uniformes en [0,1)


sa=numpy.random.random(1000)

# obtiene velocidades interpoladas aplicando la función interpoladora a los


aleatorios uniformes
vela=funin(sa)

# ordena in situ las velocidades (no es necesario)


vela.sort()

# FIGURA 1
# Histograma
# crea figura
plt.figure()

# obtiene identificador de lienzo


scn1=plt.gca()

# Pone color de fondo en el lienzo


scn1.set_axis_bgcolor((0.,0.12,0.25))

# calcula un número de barras entero


nbarras=numpy.ceil((velmay-velmen)/250.)

# El método hist grafica el histograma


scn1.hist(vela,nbarras,histtype='bar', facecolor='g', alpha=0.75,
rwidth=0.8)

# pone límites al eje de abcisas


plt.xlim([1250,7250])

# etiqueta las abcisas


plt.xlabel("Velocidad (m/s)",fontsize=14)

# etiqueta las ordenadas


plt.ylabel("Número de muestras",fontsize=14)

# pone título al histograma


plt.title("HISTOGRAMA DE VELOCIDADES",fontsize=24,
color="blue",weight="bold")

# FIGURA 2
# Diagrama de caja y violín

# Crea figura
fig2=plt.figure()

# Pone color de fondo


scn2=fig2.gca(axisbg="gray")

# El método boxplot grafica el diagrama de caja


# Muestra la media con un marcador cuadrado
scn2.boxplot(vela,showmeans=True,notch=True,boxprops={"linewidth":2},whiske
rprops={"linewidth":3},capprops={"linewidth":2},medianprops={"linewidth":3}
,labels=" ")

# Pone etiqueta al eje y


plt.ylabel("Velocidad (m/s)")

# Asegura superposición de gráficos sucesivos en una misma ventana


plt.hold(True)

# Grafica diagrama de violín, similar a un diagrama


# de caja, pero con el histograma suavizado a los lados
# El diagrama de violín no muestra la caja, por ello
# en este ejemplo se superponen los dos gráficos.
# El método violinplot grafica el diagrama de violin
# Muestra la media y la mediana con líneas
# violin es un diccionario de objetos gráficos
violin=scn2.violinplot(vela,showmeans=True,showmedians=True)

# Pone color azul a la línea de la media


# En el diccionario violin, cmeans contiene un objeto gráfico
# LineCollection para la(s) media(s)
LineCollection.set_color(violin["cmeans"],"blue")

# setp establece propiedades de objetos


# En este ejemplo se utiliza para eliminar los valores de marcas en el eje
# x
# También se puede hacer con el método: scn2.set_xticks=[]
plt.setp(scn2,xticks=[])

# Pone un título al gráfico


plt.title("DIAGRAMA DE CAJA Y VIOLÍN",fontsize=24,
color="blue",weight="bold")

# Pone malla de coordenadas


scn2.grid()

Comentarios nuevos

from matplotlib.collections import LineCollection


Importa sólo la función LineCollection del módulo collections del
paquete matplotlib.
Esta función no pertenece al módulo de funciones pyplot.
Los objetos LineCollection representan conjuntos de líneas, a las
cuales se le pueden aplicar métodos y propiedades de forma colectiva,
en lugar de individualmente.

nbarras=numpy.ceil((velmay-velmen)/250.)
Utiliza la función ceil para redondear un número hacia el entero
inmediato superior. Aquí se utiliza para calcular un número de barras
para el histograma.

scn1.hist(vela,nbarras,histtype='bar', facecolor='g', alpha=0.75,


rwidth=0.8)
Grafica el histograma (figura 7). Notar que en este ejemplo se
utiliza el método hist del objeto axes scn1, no una función.
En los argumentos obligatorios se especifican los datos (vela) y el
número de barras (nbarras).
Los argumentos opcionales son:
histtype='bar' significa que grafique un histograma de barras
facecolor='g' indica el color de relleno de las barras (verde)
alpha=0.75 indica que la opacidad del gráfico es 0.75
rwidth=0.8 indica el espacio a dejar entre barra y barra

scn2.boxplot(vela,showmeans=True,notch=True,boxprops={"linewidth":2},whiske
rprops={"linewidth":3},capprops={"linewidth":2},medianprops={"linewidth":3}
,labels=" ")
Grafica un diagrama estadístico de caja utilizando el método boxplot
del objeto axes scn2 (figura 8).
Argumento obligatorio: el arreglo de datos (vela)
Argumentos opcionales:
showmeans=True indica que debe representar la media o medias (el
arreglo de datos puede tener múltiples columnas de datos, en cuyo
caso se graficarán igual cantidad de diagramas de caja con sus
respectivas medias). El símbolo predeterminado es un pequeño
cuadrado.
notch=True indica que debe graficar el intervalo de confianza del
estimado de la mediana mediante muescas en la caja. De forma
predeterminada es el intervalo de confianza del 95%, pero esto se
puede cambiar.
boxprops={"linewidth":2} el contenido entre llaves es un diccionario
de propiedades de la caja: establece el grosor de las líneas que
limitan la caja en 2 puntos.
wiskerprops={"linewidth":3} diccionario donde se establece el grosor
de las líneas punteadas que salen de la caja en 3 puntos
capsprops={"linewidth":3} diccionario donde se establece el grosor de
las líneas transversales al extremo de las líneas punteadas en 2
puntos.
medianprops={"linewidth":3} diccionario donde se establece el grosor
de la línea de la mediana en 3 puntos.
labels=" " establece como identificador de cajas un espacio en
blanco. En este ejemplo se hace por estética, porque se graficará una
sola caja. La identificación tiene sentido cuando se muestran
múltiples cajas.

violin=scn2.violinplot(vela,showmeans=True,showmedians=True)
Utiliza el método violinplot del objeto axes scn2 para graficar un
diagrama de violín. Notar que lo hace en la misma ventana del gráfico
de caja. Pudo haberse hecho en un gráfico aparte, pero resulta mas
ilustrativo superponer las dos formas de representar los datos
estadísticos.
violinplot devuelve un diccionario de objetos gráficos. Se respalda
en "violin" porque se va necesitar a continuación.
De forma predeterminada, el gráfico de violín representa un estimado
de la función de distribución de la población en base a una muestra.
https://en.wikipedia.org/wiki/Violin_plot
Se puede seleccionar la técnica estadística utilizada para realizar
tal estimado.
https://en.wikipedia.org/wiki/Kernel_density_estimation

showmeans=True indica que grafique la línea de la media


showmedians=True indica que grafique la línea de la mediana

LineCollection.set_color(violin["cmeans"],"blue")
violinplot no permite establecer las propiedades individuales de los
objetos gráficos que componen el diagrama; por ejemplo, el color.
Como consecuencia, la línea que representa la media tiene el mismo
color que la línea que representa la mediana, haciendo difícil
identificar cual es cual.
La función LineCollection.set_color se utiliza para cambiar el color
a la línea de la media utilizando la clave cmeans en el diccionario
de objetos violin. Se establece en color azul, para diferenciarla de
la línea de la mediana que está en color rojo.

plt.setp(scn2,xticks=[])
La función setp se puede utilizar para poner o cambiar propiedades de
objetos gráficos. En este ejemplo se utiliza para eliminar las marcas
de identificación de gráficos violin, por el procedimiento de pasarle
una lista vacía. Se hace por estética, ya que sólo hay un gráfico.
Figura 7. Histograma de barras elaborado con el método hist de
Pyplot.
Figura 8. Diagrama de caja y diagrama de violín superpuestos en una
misma figura. El diagrama de caja fue realizado con el método boxplot
de un objeto axes, y el diagrama de violín con el método violinplot
del mismo objeto.
La media está indicada por el pequeño cuadro rojo en medio de la
línea azul. La mediana está en la línea roja entre las muescas de la
caja.
GRÁFICOS DE MAPAS

# Ejemplo graficación de mapas 2D

# Importa el paquete de funciones numéricas numpy


import numpy

# Importa el módulo de funciones gráficas matplotlib.pyplot


import matplotlib.pyplot as plt

# Importa las paletas de colores cm


from matplotlib import cm

def cotasp77(xx,yy,c):
# dados los arreglos de coordenadas x (xx), coordenadas y (yy) y
coeficientes c,
# calcula cotas zz con un polinomio de grado máximo 7 en x,y. Es decir, la
suma
# de la potencia de x mas la potencia de y no excede 7.
# Después se divide entre xx**8 + yy**8 + 1 para hacer que las cotas
tiendan
# a cero en el infinito.
# cálculo de potencias de x y de y
xx1=xx
xx2=xx*xx
xx3=xx2*xx
xx4=xx3*xx
xx5=xx4*xx
xx6=xx5*xx
xx7=xx6*xx
xx8=xx7*xx
yy1=yy
yy2=yy*yy
yy3=yy2*yy
yy4=yy3*yy
yy5=yy4*yy
yy6=yy5*yy
yy7=yy6*yy
yy8=yy7*yy
# cálculo de las cotas z=P77(x,y)
zz= c[0]\
+c[1]*xx1+c[2]*yy1\
+c[3]*xx2+c[4]*xx1*yy1+c[5]*yy2\
+c[6]*xx3+c[7]*xx2*yy1+c[8]*xx1*yy2+c[9]*yy3\
+c[10]*xx4+c[11]*xx3*yy1+c[12]*xx2*yy2+c[13]*xx1*yy3+c[14]*yy4\
+c[15]*xx5+c[16]*xx4*yy1+c[17]*xx3*yy2\
+c[18]*xx2*yy3+c[19]*xx1*yy4+c[20]*yy5\
+c[21]*xx6+c[22]*xx5*yy1+c[23]*xx4*yy2+c[24]*xx3*yy3\
+c[25]*xx2*yy4+c[26]*xx1*yy5+c[27]*yy6\
+c[28]*xx7+c[29]*xx6*yy1+c[30]*xx5*yy2+c[31]*xx4*yy3\
+c[32]*xx3*yy4+c[33]*xx2*yy5+c[34]*xx1*yy6+c[35]*yy7
# Se divide entre potencias octavas para reducir magnitudes hacia los
bordes
# El +1 es para evitar división entre 0 cuando xx8=yy8=0

zz=zz/(xx8+yy8+1)

# Devuelve el resultado zz
return(zz)

#--------------------------------------------------------------------------

# Datos para cálculos


xi=-3.0 # coordenada extremo inferior
xs=3.0 # coordenada extremo superior
dx=0.1 # intervalo de malla
nalea=10000 # número de puntos aleatorios

# coordenadas x de puntos aleatorios


xx=(xs-xi)*numpy.random.random_sample((nalea,))+xi

# coordenadas y de puntos aleatorios


yy=(xs-xi)*numpy.random.random_sample((nalea,))+xi

# coeficientes aleatorios enteros de polinomio 2D grado 7 máximo en x, y


# 398010574215107679422058885600836061208944572721 mapas posibles
# Una colección de coeficientes que produce mapa bonito:
# c=[-3,10,-9,3,6,-7,4,0,-8,1,-4,4,-5,
# -5,-5,1,9,-6,5,0,7,-4,-1,8,-8,2,
# 0,-3,7,-10,7,-7,10,-6,-5,10]
#
# c=[-1,5,-6,-10,3,7,-10,2,-3,3,2,-7,-4,
# 8,-9,5,9,8,-4,0,-7,1,7,7,-7,8,
# 0,0,2,5,8,-8,6,10,9,-4]

c=numpy.random.random_integers(-10,10,36)

# Utiliza la función cotasp77 para calcular las cotas zz en los puntos


aleatorios (xx,yy)
zz=cotasp77(xx,yy,c)

# Las siguientes instrucciones son para calcular las


# cotas de 21 contornos

# encuentra el máximo absoluto de cota y lo redondea hacia arriba


mami=numpy.ceil(max(abs(zz)))
# cota mínima redondeada hacia abajo
ini=-mami

# cota máxima redondeada hacia arriba


fin= mami

# intervalo de contornos
inter=numpy.round((2*mami)/20)

# arreglo de cotas de contornos


contornos=numpy.arange(ini,fin+inter,inter)

#
# FIGURA 1
# Mapa de contornos creados por triangulación de puntos de cota

# Activa modo interactivo para que muestre los gráficos automáticamente


plt.ion()

# cierre preventivo de gráficos


plt.close("all")

# abre una ventana de graficación


plt.figure()

# establece color de fondo en la ventana


plt.axes(axisbg="black")

# gráfico de líneas de contorno con tricontour


idf=plt.tricontour(xx,yy,zz,contornos,linewidths=2,cmap="seismic")

# etiquetas de cota en los contornos


plt.clabel(idf,fontsize=10,fmt="%1.1f")

# pone título del gráfico


plt.title("Mapa usando tricontour",fontsize=24)

# pone barra identificadora de líneas de contorno


plt.colorbar().set_label("Cota (m)")

# pone malla de coordenadas


plt.grid(color="white")
#
# FIGURA 2
# Mapa con relleno entre contornos creados por triangulación de puntos de
cota
# abre nueva ventana gráfica
plt.figure()

# gráfica con relleno de cotas con tricontourf


idg=plt.tricontourf(xx,yy,zz,contornos,cmap="bwr")

# pone título al gráfico


plt.title("Mapa usando tricontourf",fontsize=24)

# pone barra identificadora de colores


plt.colorbar(idg).set_label("Cota (m)")

# Asegura superposición de gráficos sucesivos en una misma ventana


plt.hold(True)

# grafica la línea de cota 0 con tricontour


idf=plt.tricontour(xx,yy,zz,[0],linewiths=2,colors=[(0.461880,0.461880,0.46
1880)])

# etiqueta la única línea de cota


plt.clabel(idf,fontsize=10,fmt="%1.1f",colors="black")

# pone malla de coordenadas


plt.grid(color="black")

#FIGURA 3
# Coordenadas x,y en mallado regular

# arreglo 1D de puntos equiespaciados. Incluye extremo


x=numpy.arange(xi,xs+dx,dx,dtype=float)

# Obtiene los arreglos de coordenadas de puntos en mallado. En este ejemplo


el arreglo de puntos en y es igual al arreglo de puntos en x
XX,YY=numpy.meshgrid(x,x)

# calcula las cotas ZZ en los puntos (XX,YY) del mallado con la función
cotasp77
ZZ=cotasp77(XX,YY,c)

# nueva ventana gráfica


plt.figure()

# grafica interpolando con imshow


# es necesario colocar los límites de coordenadas x,y
# en extent para que concuerden con los reales
idg = plt.imshow(ZZ, interpolation='lanczos', origin='lower', extent=[xi,
xs, xi, xs],vmax=fin, vmin=ini, cmap=cm.terrain)

# pone título al gráfico


plt.title("Mapa usando imshow",fontsize=24)

# pone barra identificadora de colores


# es necesario especificar vmax y vmin en imshow para que los límites de la
barra coincidan con los rangos de cotas del mapa

plt.colorbar(idg).set_label("Cota (m)")

Comentarios

from matplotlib import cm


Importa funciones y propiedades de paletas de colores, útiles para
colorear mapas

def cotasp77(xx,yy,c):
Define una función de usuario llamada cotasp77, con tres argumentos
obligatorios

xx=(xs-xi)*numpy.random.random_sample((nalea,))+xi
yy=(xs-xi)*numpy.random.random_sample((nalea,))+xi
Obtiene abcisas (xx) y ordenadas (yy) de puntos aleatorios de
distribución uniforme usando la función random_samples. Un sinónimo
de esta función es "random".
En el argumento, el número de puntos aletorios (nalea) se especifica
en una tupla. Como se trata de un arreglo de una sola dimensión, debe
ponerse una coma en la tupla.
Los puntos aleatorios quedan distribuidos uniformente en el intervalo
[xi,xs]

zz=cotasp77(xx,yy,c)
Utiliza la función de usuario cotasp77 para obtener valores zz en los
puntos aleatorios (xx,yy)
El arreglo c contiene los coeficientes de un polinomio 2D de grado
máximo 7 en x,y

mami=numpy.ceil(max(abs(zz)))
Determina el máximo absoluto de las zz calculadas, redondeando hacia
el entero mayor mas cercano

inter=numpy.round((2*mami)/20)
Calcula el intervalo entre contornos, para 21 contornos. La función
numpy.round redondea hacia el entero mas cercano.

contornos=numpy.arange(ini,fin+inter,inter)
Obtiene un arreglo con los valores de los contornos usando la función
arange de Numpy.
Notar que para el límite de la sucesión geométrica se usó fin+inter,
con la finalidad de que incluya el valor de "fin" en el arreglo.
idf=plt.tricontour(xx,yy,zz,contornos,linewidths=2,cmap="seismic")
Grafica mapa de contornos con la función tricontour (figura 9).
Tricontour crea triángulos bajo la condición de Delaunay con los
puntos suministrados, los cuales utiliza para calcular los contornos.
idf es el identificador del objeto gráfico que devuelve tricontour.
Argumentos obligatorios:
xx, yy, zz: coordenadas 3D de los puntos
contornos: arreglo con los valores de los contornos a graficar
Argumentos opcionales:
cmap="seismic" elige la paleta de colores denominada "seismic" cuyo
rango es desde azul hasta rojo, con blanco en la mitad.

plt.clabel(idf,fontsize=10,fmt="%1.1f")
Pone etiquetas a los contornos (donde sea posible hacerlo).
En los argumentos, idf identifica el objeto que contiene los
contornos.
fontsize=10 es el tamaño de letra de las etiquetas en puntos
fmt="%1.1f" indica el formato del número que indica la cota. Al menos
1 dígito en la parte entera, y 1 decimal en la parte fraccionaria,
número en punto flotante

plt.colorbar().set_label("Cota (m)")
Agrega una escala de colores al gráfico. Las cotas serán
identificadas por líneas de diferente color. Además le pone una
identificación a la escala.

idg=plt.tricontourf(xx,yy,zz,contornos,cmap="bwr")
Grafica un mapa de contornos con relleno de color, usando la función
tricontourf (figura 10). Como paleta de colores utiliza una
denomidada "bwr" que significa: azul blanco rojo. Similar a la paleta
"seismic".

plt.colorbar(idg).set_label("Cota (m)")
Agrega escala de colores al mapa. Además identifica las unidades.

idf=plt.tricontour(xx,yy,zz,[0],linewiths=2,colors=[(0.461880,0.461880,0.46
1880)])
Grafica la línea de contorno zz=0 sobre el gráfico de tricontourf.
Esto ayuda visualmente a distinguir el límite entre cotas positivas y
negativas. El color especificado es gris, de la misma intensidad que
el color central en la paleta denominada "viridis".
Si existiesen mas líneas de cota, sería posible especificar el grosor
y color de cada línea individualmente pasando arreglos en las
opciones linewidts y colors (por eso en plural).

plt.clabel(idf,fontsize=10,fmt="%1.1f",colors="black")
Pone la etiqueta de cota a la única línea de cota
x=numpy.arange(xi,xs+dx,dx,dtype=float)
Crea un arreglo para coordenadas, con valor inicial xi y valor final
xs, a intervalos dx.
Se utiliza xs+dx para que incluya xs en el rango.

XX,YY=numpy.meshgrid(x,x)
Crea arreglos de coordenadas de puntos en un mallado regular.
En este ejemplo el mallado es cuadrado, pero pudiera ser rectangular.
Si las coordenadas y fuesen distintas a las x se utilizaría:
XX,YY=numpy.meshgrid(x,y); pero en este ejemplo y=x.
El arreglo XX contiene solo las coordenadas x de los puntos del
mallado, y el arreglo YY solo las coordenadas y.

idg = plt.imshow(ZZ, interpolation='lanczos', origin='lower', extent=[xi,


xs, xi, xs],vmax=fin, vmin=ini, cmap=cm.terrain)
Grafica mapa con la función imshow (figura 11). Esta función es solo
para imágenes, incluyendo las de formato png, jpg, etc.
Argumentos obligatorios:
ZZ: valores de la imagen en cada pixel
Argumentos opcionales:
interpolation='lanczos': método de interpolación de la imagen
origin='lower': de forma predeterminada, el origen de coordenadas de
las imágenes es la esquina superior izquierda. Esta opción la cambia
a la parte inferior izquierda. Sinó, la imagen del mapa saldría
volteada respecto al sistema de coordenadas utilizado en los
cálculos. Alternativamente, en lugar de imshow se puede usar la
función matshow, la cual grafica como imagen el contenido de una
matriz, con origen de coordenadas en el extremo inferior izquierdo.
extent=[xi, xs, xi, xs]: una imagen en principio no tiene
coordenadas, excepto por la numeración de pixeles en x,y: [0,0],
[0,1], [0,2], ... Esta opción le asigna coordenadas en x y en y para
que coincidan con las del mapa que se representa como imagen.
vmax=fin, vmin=ini: establece los valores de cota máxima y mínima en
la imagen. Al igual que las coordenadas x,y la imagen no tiene
coordenada z, excepto por las intensidades de colores. Además, estos
valores serán los utilizados para establecer los límites en la escala
de colores.
cmap=cm.terrain: especifica la paleta de colores llamada "terrain"
Figura 9. Mapa creado con la función tricontour. El rango de valores
ha sido centrado para que el color blanco corresponda con la cota 0.
Figura 10. Mapa creado usando la función tricontourf. El rango de
valores ha sido centrado para que el color blanco corresponda con la
cota 0. Se superpuso la línea de cota z=0 con la función tricontour.
Figura 11. Mapa imagen creado con imshow. El rango de valores ha sido
centrado para que el color central de la escala corresponda con la
cota 0.
# Ejemplo de graficación de puntos, líneas y superficies 3D

# Importa el paquete de funciones numéricas numpy


import numpy

# Importa el módulo de funciones gráficas matplotlib.pyplot


import matplotlib.pyplot as plt

# Importa funciones para gráficos 3D


from mpl_toolkits.mplot3d import Axes3D

# Importa las paletas de colores cm


from matplotlib import cm

# Importa funciones de temporizador


import time

# Toma el tiempo inicial


t0=time.time()

def cotasp77(xx,yy,c):
# dados los arreglos de coordenadas x (xx), coordenadas y (yy) y
coeficientes c,
# calcula cotas zz con un polinomio de grado máximo 7 en x,y. Es decir, la
suma
# de la potencia de x mas la potencia de y no excede 7.
# Después se divide entre xx**8 + yy**8 + 1 para hacer que las cotas
tiendan
# a cero en el infinito.
# cálculo de potencias de x y de y
# Este método es mas rápido que utilizar la función pow
# pero el resultado puede ser menos preciso, excepto si
# todas las cantidades son enteros
xx1=xx
xx2=xx*xx
xx3=xx2*xx
xx4=xx3*xx
xx5=xx4*xx
xx6=xx5*xx
xx7=xx6*xx
xx8=xx7*xx
yy1=yy
yy2=yy*yy
yy3=yy2*yy
yy4=yy3*yy
yy5=yy4*yy
yy6=yy5*yy
yy7=yy6*yy
yy8=yy7*yy
# cálculo de las cotas z=P77(x,y)
zz= c[0]\
+c[1]*xx1+c[2]*yy1\
+c[3]*xx2+c[4]*xx1*yy1+c[5]*yy2\
+c[6]*xx3+c[7]*xx2*yy1+c[8]*xx1*yy2+c[9]*yy3\
+c[10]*xx4+c[11]*xx3*yy1+c[12]*xx2*yy2+c[13]*xx1*yy3+c[14]*yy4\
+c[15]*xx5+c[16]*xx4*yy1+c[17]*xx3*yy2\
+c[18]*xx2*yy3+c[19]*xx1*yy4+c[20]*yy5\
+c[21]*xx6+c[22]*xx5*yy1+c[23]*xx4*yy2+c[24]*xx3*yy3\
+c[25]*xx2*yy4+c[26]*xx1*yy5+c[27]*yy6\
+c[28]*xx7+c[29]*xx6*yy1+c[30]*xx5*yy2+c[31]*xx4*yy3\
+c[32]*xx3*yy4+c[33]*xx2*yy5+c[34]*xx1*yy6+c[35]*yy7
# Se divide entre potencias octavas para reducir magnitudes hacia los
bordes
# El +1 es para evitar división entre 0 cuando xx8=yy8=0
zz=zz/(xx8+yy8+1)
return(zz)

#--------------------------------------------------------------------------

xi=-3.0 # coordenada extremo inferior


xs=3.0 # coordenada extremo superior
dx=0.1 # intervalo de malla
nalea=10000 # número de puntos aleatorios

# coordenadas x de puntos aleatorios


xx=(xs-xi)*numpy.random.random_sample((nalea,))+xi

# coordenadas y de puntos aleatorios


yy=(xs-xi)*numpy.random.random_sample((nalea,))+xi

# coeficientes aleatorios enteros de polinomio 2D grado 7 máximo en x, y


# 398010574215107679422058885600836061208944572721 mapas posibles
# Una colección de coeficientes que produce mapa bonito:
# c=[-3,10,-9,3,6,-7,4,0,-8,1,-4,4,-5,
# -5,-5,1,9,-6,5,0,7,-4,-1,8,-8,2,
# 0,-3,7,-10,7,-7,10,-6,-5,10]
#
# c=[-1,5,-6,-10,3,7,-10,2,-3,3,2,-7,-4,
# 8,-9,5,9,8,-4,0,-7,1,7,7,-7,8,
# 0,0,2,5,8,-8,6,10,9,-4]

c=numpy.random.random_integers(-10,10,36)

# Utiliza la función cotasp77 para calcular las cotas zz en los puntos


aleatorios (xx,yy)
zz=cotasp77(xx,yy,c)
# Las siguientes instrucciones son para calcular las
# cotas de 21 contornos
# encuentra el máximo absoluto de cota y lo redondea hacia arriba
mami=numpy.ceil(max(abs(zz)))

# cota mínima redondeada hacia abajo


ini=-mami

# cota máxima redondeada hacia arriba


fin= mami

# intervalo de contornos
inter=numpy.round((2*mami)/20)

# arreglo de cotas de contornos


contornos=numpy.arange(ini,fin+inter,inter)

# Activa modo interactivo para que muestre los gráficos automáticamente


plt.ion()

# cierre preventivo de gráficos previos


plt.close("all")

#
# FIGURA 1
# Puntos dispersos en 3D

# abre una ventana gráfica


fig=plt.figure()

# obtiene objeto gráfico scn, establece la proyección como gráfico 3D y el


color de fondo
scn=fig.gca(projection="3d",axisbg="white")

# scatter grafica puntos aislados en 3D


scn.scatter(xx,yy,zz,marker=".",s=0.1)

# pone etiqueta al eje x


scn.set_xlabel('Eje x',color="green")

# pone etiqueta al eje y


scn.set_ylabel('Eje y',color="green")

# pone etiqueta al eje z


scn.set_zlabel('Eje z',color="green")

# pone título al gráfico


scn.set_title("3D CON SCATTER",fontsize=14,color="blue",weight="bold")

#
# FIGURA 2
# Superficie en 3D con facetas triangulares

# abre nueva ventana gráfica


fig=plt.figure()

# obtiene objeto gráfico scn, establece la proyección como gráfico 3D y el


color de fondo
scn=fig.gca(projection="3d",axisbg="white")

# trisurf grafica mapa de triángulos en puntos 3D


# Adecuado si los puntos pertenecen a una superficie continua en 3D.
Inadecuado si forman una "nube" en 3D.
scn.plot_trisurf(xx,yy,zz,cmap=cm.terrain,linewidth=0,vmax=fin, vmin=ini)

# pone etiqueta al eje x


scn.set_xlabel('Eje x',color="green")

# pone etiqueta al eje y


scn.set_ylabel('Eje y',color="green")

# pone título al gráfico


scn.set_title("3D CON TRISURF",fontsize=14,color="blue",weight="bold")

# arreglo 1D de puntos equiespaciados. Incluye extremo


x=numpy.arange(xi,xs+dx,dx,dtype=float)

# Obtiene los arreglos de coordenadas de puntos


# en mallado. En este ejemplo el arreglo de puntos
# en y es igual al arreglo de puntos en x
XX,YY=numpy.meshgrid(x,x)

# calcula las respectivas cotas ZZ


ZZ=cotasp77(XX,YY,c)

#
# FIGURA 3
# Superficie en 3D con mallado de puntos

# abre nueva ventana gráfica


fig=plt.figure()

# obtiene objeto gráfico scn, establece la proyección como gráfico 3D y el


color de fondo
scn=fig.gca(projection="3d",axisbg="white")
# plot_surface grafica superficie con relleno de facetas.
# vmax y vmin para que la barra de colores concuerde
# simétricamente con los valores de cota
# defecto: produce superficie semitransparente
superf=scn.plot_surface(XX, YY, ZZ,rstride=1,cstride=1,vmax=fin,
vmin=ini,cmap=cm.jet,linewidth=0.1,shade=False,antialiased=True)

# pone etiqueta al eje x


scn.set_xlabel('Eje x',color="green")

# pone etiqueta al eje y


scn.set_ylabel('Eje y',color="green")

# pone título al gráfico


scn.set_title("3D CON PLOT_SURFACE",fontsize=14,color="blue",weight="bold")

# pone barra de escala de colores


fig.colorbar(superf).set_label("Cota (m)")
# También sirve:
# plt.colorbar(superf)

#
# FIGURA 4
# Mallado de superficie en 3D sin relleno con
# líneas de contorno y proyección sobre el
# plano xy

# abre nueva ventana gráfica


fig=plt.figure()

# obtiene objeto gráfico scn, establece la proyección como gráfico 3D y el


color de fondo
scn=fig.gca(projection="3d",axisbg="white")

# plot_wireframe grafica un mallado sin relleno, de un conjunto de puntos


en 3D
superf=scn.plot_wireframe(XX, YY, ZZ, rstride=1, cstride=1, linewidth=0.1,
color="green")
# otra opción: facecolor="color", rellena de color
# entre cota 0 y la línea

# Asegura superposición de gráficos sucesivos en una misma ventana


plt.hold(True)

# contour3D grafica líneas de contornos en el espacio (pero no la


superficie).
# Es mas útil si se grafica también la superficie con otra función.
# contour3D también con nombre contour
ids=scn.contour3D(XX,YY,ZZ,contornos,cmap=cm.jet)

# obtiene la cota del plano horizontal inferior del gráfico


zinf=scn.get_zbound()[0]

# contourf3D grafica contornos rellenos proyectados sobre el plano


horizontal inferior.
# defecto: deja áreas en blanco en la proyección
scn.contourf3D(XX,YY,ZZ,contornos,cmap=cm.jet,zdir="z",offset=zinf)

# pone etiqueta al eje x


scn.set_xlabel('Eje x',color="green")

# pone etiqueta al eje y


scn.set_ylabel('Eje y',color="green")

# pone título al gráfico


scn.set_title("3D CON WIREFRAME, CONTOUR3D Y
CONTOURF3D",fontsize=14,color="blue",weight="bold")

#
# FIGURA 5
# Líneas en 3D con plot3D

# abre nueva ventana gráfica


fig=plt.figure()

# obtiene objeto gráfico scn, establece la proyección como gráfico 3D y el


color de fondo
scn=fig.gca(projection="3d",axisbg="white")

# Asigna "not a number"


nan=float("nan")

# plot3D grafica líneas en 3D si se dan x, y, z. En 2D si sólo se dan x, y


# Grafica facetas de base horizontal y tope inclinado de un prisma
triangular
# Utiliza nan para producir líneas discontinuas
superf=scn.plot3D([1,4,3,1,nan,1,4,3,1],[2,3,5,2,nan,2,3,5,2],[6,3,5,6,nan,
0,0,0,0,],color="blue")

# Establece coordenadas esféricas del punto de observación.


scn.azim=-50 # azimut (grados). Predet.= -60
scn.elev=15 # elevación (grados). Predet.= 30
scn.dist=12 # distancia radial. Predet.= 10

# pone etiqueta al eje x


scn.set_xlabel('Eje x',color="green")

# pone etiqueta al eje y


scn.set_ylabel('Eje y',color="green")

# pone un título al gráfico


scn.set_title("PLOT3D",fontsize=14,color="blue",weight="bold")

# imprime el tiempo empleado para este programa


print("tiempo=",time.time()-t0,"s")

Comentarios

import time
Las funciones del paquete time se usan para aplicaciones donde se
necesite conteo de tiempo

t0=time.time()
Toma el tiempo inicial según el reloj de la máquina, en segundos.

scn.scatter(xx,yy,zz,marker=".",s=0.1)
El método scatter del objeto scn grafica puntos dispersos en 3D
(figura 12).
Requiere como argumentos obligatorios 3 arreglos con las coordenadas
x,y,z
La opción marker="." indica que los puntos en el espacio serán
representados con símbolos marcadores de puntos
La opción s=0.1 indica el tamaño de los marcadores.

scn.plot_trisurf(xx,yy,zz,cmap=cm.terrain,linewidth=0,vmax=fin, vmin=ini)
El método plot_trisurf del objeto axes scn, grafica una superficie de
facetas triangulares en 3D (figura 13).
Los argumentos obligatorios son arreglos con las coordenadas x,y,z de
los puntos.
cmap=cm.terrain: indica una paleta de colores
linewidth=0: el grosor de las líneas de las aristas de los
triángulos. Se puso espesor 0 para que no las grafique.
vmax=fin, vmin=ini: valores máximos y mínimos de coordenada z en el
gráfico. Serán utilizados también para establecer los límites en la
escala de colores.
Este gráfico es útil si los puntos pertenecen a una superficie en 3D.

superf=scn.plot_surface(XX, YY, ZZ,rstride=1,cstride=1,vmax=fin,


vmin=ini,cmap=cm.jet,linewidth=0.1,shade=False,antialiased=True)
El método plot_surface del objeto axes scn grafica una superficie 3D
con los puntos de un mallado regular rellenando de color (figura 14).
Los argumentos obligatorios son arreglos con las coordenadas x,y,z de
los puntos.
Argumentos opcionales:
rstride=1: intervalo de filas para dibujar las líneas del mallado en
la superficie 3D
rstride=1: intervalo de columnas para dibujar las líneas del mallado
en la superficie 3D
vmax=fin, vmin=ini: valores máximos y mínimos de coordenada z en el
gráfico. Serán utilizados también para establecer los límites en la
escala de colores.
cmap=cm.jet: utiliza paleta de colores denominada "jet"
linewidth=0.1: grosor de las líneas del mallado
shade=False: sombreado de las facetas desactivado
antialiased=True: activar reducción del aliasing al graficar

superf=scn.plot_wireframe(XX, YY, ZZ, rstride=1, cstride=1, linewidth=0.1,


color="green")
El método plot_wireframe del objeto axes scn grafica un mallado de
líneas sobre una superficie 3D, sin relleno (figura 15).
Los argumentos obligatorios son arreglos con los valores x,y,z de los
puntos del mallado.
rstride=1: intervalo de filas para dibujar las líneas del mallado en
la superficie 3D
rstride=1: intervalo de columnas para dibujar las líneas del mallado
en la superficie 3D
linewidth=0.1: grosor de las líneas del mallado
color="green": color de las líneas del mallado

ids=scn.contour3D(XX,YY,ZZ,contornos,cmap=cm.jet)
El método contour3D del objeto axes scn dibuja contornos de cota en
espacio 3D. Sólo dibuja los contornos en el espacio. Resulta mas útil
si se dibujan en el mismo gráfico que producen plot_trisurf,
plot_surface o plot_wireframe, como en este ejemplo (figura 15).
Argumentos obligatorios: arreglos con las coordenadas x,y,z de los
puntos del mallado y un arreglo con los valores z de los contornos
deseados.
cmap=cm.jet: utilizar la paleta de colores denominada "jet"

zinf=scn.get_zbound()[0]
El método gez_zbound del objeto axes scn obtiene una lista con los
límites z (inferior y superior) del gráfico. En este caso se toma
solo el límite inferior.

scn.contourf3D(XX,YY,ZZ,contornos,cmap=cm.jet,zdir="z",offset=zinf)
El método contourf3D produce contornos de cota z, rellenos en 3D.
Visualmente semejan bandas horizontales en el espacio. Resultan de
mayor utilidad si se proyectan sobre uno o varios planos. En este
ejemplo se proyectan sobre un plano xy de cota z=zinf (figura 15).
Los argumentos obligatorios son arreglos con los valores x,y,z de los
puntos del mallado y un arreglo con los valores z de los contornos
deseados.
cmap=cm.jet: utilizar la paleta de colores denominada "jet"
zdir="z": dirección de proyección de las bandas de contornos de cota
offset=zinf: cota del plano xy sobre el que se proyectan los
contornos.

nan=float("nan")
Asigna a una variable llamada nan un tipo de objeto denominado "nan",
de "not a number", que se utiliza por ejemplo para designar
resultados que no están definidos, tal como la división 0/0

superf=scn.plot3D([1,4,3,1,nan,1,4,3,1],[2,3,5,2,nan,2,3,5,2],[6,3,5,6,nan,
0,0,0,0,],color="blue")
El método plot3D del objeto axes scn grafica líneas entre puntos
sucesivos en 2D o en 3D (figura 16).
Como argumentos obligatorios se pueden dar arreglos con las
coordenadas x,y para gráficos 2D, o arreglos x,y,z para gráficos en
3D.
En este ejemplo se dan 3 arreglos con las coordenadas x,y,z
respectivamente.
En los arreglos se incluyó un punto de coordenadas (nan,nan,nan) con
el objeto de interrumpir el trazado de rectas entre puntos sucesivos.
Esto es útil para graficar líneas discontínuas. De esta forma se pudo
lograr dibujar dos triángulos separados.

scn.azim=-50 # azimut (grados). Predet.= -60


scn.elev=15 # elevación (grados). Predet.= 30
scn.dist=12 # distancia radial. Predet.= 10
Los métodos azim, elev y dist establecen las coordenadas esféricas
del punto de observación del gráfico (azimut, elevación, distancia).
Los valores predeterminados son:
azim=-60 (grados)
elev= 30 (grados)
dist= 10 (unidades de distancia en el gráfico)

print("tiempo=",time.time()-t0,"s")
Imprime el tiempo total (este programa+otros programa+sistema
operativo) utilizado desde inicio del programa hasta su terminación.
La opción "s" indica que el tiempo debe estar expresado en segundos.
Figura 12. Gráfico 3D de puntos dispersos elaborado por el método
scatter de un objeto axes.
Figura 13. Gráfico de superficie 3D de facetas triangulares elaborado
por el método plot_trisurf de un objeto axes.
Figura 14. Gráfico de superficie 3D en un mallado regular, elaborado
por el método plot_surface de un objeto axes.
Figura 15. Gráfico de líneas de mallado de una superficie 3D,
elaborado por el método plot_wireframe de un objeto axes.
Superpuestas a la malla están líneas de contornos, elaboradas por el
método contour3D del mismo objeto axes.
Proyectados en un plano horizontal están los contornos de cotas
rellenos, elaboradas por el método contourf3D del objeto axes.
Figura 16. Gráfico de líneas en 3D elaborado por el método plot3D de
un objeto axes. Los triángulos representados están desconectados,
debido a que se incluyó un punto nan en los arreglos de coordenadas.

Superposición de gráficos
De forma predeterminada en matplotlib los gráficos se superponen en
una ventana abierta.
Para desactivar esta característica, tal que cada vez que se grafique
se borre el gráfico previo usar:
plt.hold(False)

Para reactivar la superposición usar:


plt.hold(True)
DEPURANDO CON IEP/Pyzo

1- Colocar un punto de interrupción para depuración. Para ello en el


editor hacer click en el borde derecho de la columna de numeración de
líneas, a nivel del sitio donde se sospecha el error. Marcará el
punto con un punto rojo antes de la próxima instrucción a ejecutar.
Se pueden insertar la cantidad de puntos de interrupción que se
desee, antes o durante la depuración.
Se borra un punto haciendo click sobre él.

Si se coloca un punto de interrupción antes de una línea en blanco,


el depurador no lo reconoce y ejecuta el programa como si no
existiese.

2- Ejecutar el programa con Ctrl E o F5.


El programa se detendrá en el primer punto de interrupción que
encuentre.
El punto actual de ejecución lo indica con un guión verde en el borde
derecho de la columna de numeración de líneas. Inicialmente
coincidirá con el punto de interrupción.
También se activan los íconos de depuración en la parte superior
derecha de la ventana del shell.
El indicador del shell cambiará a: (<module>)>>> para indicar que se
está en modo depuración.

3- Se puede avanzar con la depuración con los íconos, o con comandos


en el shell.
Los comandos de depuración en el shell se pueden listar con: db help

Para salir del depurador: db stop o ícono de X roja en la parte


superior derecha de la ventana del shell.

Depuración postmortem.
Se puede invocar cuando se interrumpe un programa con Ctrl I, o
cuando ocurre un error que detiene el programa, por ejemplo división
entre cero.
Entonces se puede activar la depuración postmortem con:
En el menú principal de IEP: Consola  Postmortem: Depurar desde el
último tracebak
O bién en el shell: db start
Sin embargo, aquí no se activan los íconos de depuración. Sólo está
activa la pila de llamadas y se enciende el indicador de posición
guión verde en la columna de numeración de líneas del editor. Esto es
una ayuda visual para determinar donde ocurrió el error.
MÓDULO MPMATH
Para precisión arbitraria con números punto flotante

Instalación

Desde un shell Ipython instalar con:


conda install mpmath

Tipos de números
mpmath tiene objetos para flotantes y complejos que se indican como
mpf y mpc, respectivamente.

Conversión a ojetos mpmath


Se utiliza la función mpmathify para convertir números Python a
flotante o complejo mpmath.
Con las constantes se debe usar el argumento entre comillas para
asegurar la conversión completa a la precisión establecida.

mpmath.mpmathify(3)  mpf('3.0')
mpmath.mpmathify(0.1)  mpf('0.10000000000000001')
mpmath.mpmathify("0.1")  mpf('0.10000000000000001')
mpmath.mpmatthfy(3+4j)  mpc(real='3.0', imag='4.0')

Estableciendo la precisión
Se puede establecer especificando en dígitos decimales o en bits de
la mantisa.
Si se especifica en uno, mpmath ajusta el otro.
La relación es: bits=decimales*log2(10), (aprox. 3.3219)

Ejemplo:
mpmath.mp.dps=30 (en dígitos decimales)
mpmath.mp.prec=100 (en bits)

La precisión se puede cambiar localmente usando instrucciones with o


decoradores en funciones

El error en la representación de un número depende de la cantidad de


bits de la mantisa. Para un mismo número el error puede ser por
exceso o por defecto según la cantidad de bits de precisión
utilizados.
El error es cero si la parte decimal del número es una potencia
negativa de 2 y se utilizan suficientes dígitos.
Por ejemplo: 3.0078125 tiene representación exacta con 8 o mas
dígitos porque la parte decimal es igual a 1/128

Declarando un número como real o complejo de mpmath


x=mpmath.mpf("3.2") x es real
z=mpmath.mpc("3.2") z es complejo

No existe una declaración para enteros porque en Python los enteros


no tienen límite a la cantidad de dígitos

Para que mpmath realmente trabaje con la precisión deseada es


necesario tener mucho cuidado.
- Todas las constantes y variables SIEMPRE deben ser pasadas como
caracteres a las funciones.
Ejemplos:

mpmath.mp.dps=88

Forma incorrecta:
mpmath.mpf(3.2)  mpf('3.20000000000000017763568394')

Formas correctas:
mpmath.mpf("3.2")  mpf('3.200000000000000000000000003')
mpmath.mpf(str(3.2))  mpf('3.200000000000000000000000003')

Forma incorrecta:
x=3.2
mpmath.mpf(x)  mpf('3.20000000000000017763568394')

Forma correcta:
x=3.2
mpmath.mpf(str(x))  mpf('3.200000000000000000000000003')

- A diferencia de gmpy2, en las operaciones todos los operandos deben


ser objetos mpf o mpc para que el resultado esté en la precisión
completa.

Ejemplo:
Forma incorrecta:
x=3.2
mpmath.mpf(str(x))*x  mpf('10.24000000000000056843418863')

Forma correcta:
x=3.2
mpmath.mpf(str(x))* mpmath.mpf(str(x))
mpf('10.24000000000000000000000001')

mpmath reconoce los operadores aritméticos normales: +, -, *, /, %,


** para realizar operaciones con objetos mpf, mpc
Las funciones equivalentes son:
+ = mpmath.fadd()
- = mpmath.fsub()
* = mpmath.fmul()
/ = mpmath.fdiv()
% = mpmath.fmod()
** = mpmath.pow()
negativo = mpmath.fneg()

Estas funciones tienen además argumentos opcionales para establecer


la precisión de la operación y el tipo de redondeo.
Opciones:
redondeo rounding= "n", "f", "c", "d", "u"
precisión prec = cantidad en bits, o +inf
precisión dps = cantidad en dígitos
precisión exact = True o False (True equivale a prec=+inf)

mpmath, aunque no es vectorial puede producir resultados en listas o


tuplas:
lista=mpmath.arange(1,3)  produce una lista de objetos mpf

Una lista de objetos mpf puede ser convertida en un arreglo numpy:


arreglonp=numpy.array(lista)

El arreglo Numpy puede usarse para realizar operaciones aritméticas


con precisión de mpmath a cada elemento, por ejemplo:

arreglonp*mpmath.mpf("3.2")
realiza la multiplicación a precisión completa de los elementos del
arreglo por el escalar. El resultado es otro arreglo de numpy con
elementos que son objetos mpf.

Lo que no puede hacerse es utilizar directamente el arreglo numpy


como argumento de funciones numpy o de mpmath.
Para ello hay que recurrir a los métodos mas lentos de comprensiones
o mapas.

Ejemplo:
Calcular con precisión de mpmath el coseno de los elementos de un
arreglo numpy que contiene objetos mpf:
list(map(mpmath.cos,listanp))  produce lista de objetos mpf

numpy.array(list(map(mpmath.cos,listanp))  produce arreglo numpy de


objetos mpf

Impresión de números mpf, mpc


En el shell de Python, se imprimen los objetos mpf, mpc como cadenas
de caracteres, pero si se trata de un programa es necesario utilizar
la funciones nstr y nprint.
nstr convierte un objeto mpf o mpc a cadena de caracteres, con una
precisión específica. La cadena se puede utilizar para guardar en un
archivo o imprimir.
Si x es un objeto mpf, lo siguiente devuelve una cadena con 20
dígitos significativos:
cadena=mpmath.nstr(x,20)

Imprimir directamente la cadena:


nprint(x,20)

Gráficos
Son gráficos muy básicos, solo para tener una vista rápida de la
forma de las funciones.
Produce tres tipos de gráficos simples: de curvas, de números
complejos y superficies 3D.
Requiere que esté instalado matplotlib.

Curvas
Forma genérica:
mpmath.plot(funcion, xlim=[xi,xs], ylim=[yi,ys], points=n,
singularities=[s1,s2,...]) (existen mas argumentos)

funcion: la función a graficar. Puede ser una lista de funciones.

xlim, ylim: límites del gráfico en el eje x y en el eje y


Si no se especifican, xlim=[-5,5]

points: número de puntos para graficar la curva. Predeterminado = 200

Singularities: lista de abcisas donde la función es singular

Ejemplo:
plot(log)  grafica la función logaritmo en el intervalo [-5,5].
En las abcisas negativas la función es compleja,
entonces representa la parte real como curva segmentada
y la imaginaria como curva aserrada
MÓDULO GMPY2
Aritmética y funciones de precisión arbitraria.

El módulo mpmath puede usar enteros de gmpy, que hace las operaciones
mas rápidas, según http://mpmath.org/doc/current/setup.html

Este módulo no pertenece al conjunto de Anaconda, por lo que no se


puede instalar con conda.
Se debe bajar el instalador para Windows:
https://code.google.com/p/gmpy/downloads/list

Ejecutar el instalador, por ejemplo: gmpy2-2.0.3.win-amd64-py3.4.exe,


el cual detectará la ubicación de Python del paquete Pyzo por la
información en el Registro de Windows y lo instalará en:
C:\pyzo2015a
Para desinstalar gmpy2 ejecutar: C:\pyzo2015a\Removegmpy2.exe

Páginas de red:
Ejemplos breves de uso:
https://gmpy2.readthedocs.org/en/latest/overview.html
https://code.google.com/p/gmpy/wiki/UsingGmpy2AndMpfr

Como instalar:
https://code.google.com/p/gmpy/wiki/InstallingGmpy2

Documentación:
https://gmpy2.readthedocs.org/en/latest/index.html

Para usar el módulo, incluir la instrucción:


import gmpy2

El contexto de precisión, comportamiento, etc de gmpy2 se obtiene


con:
gmpy2.get_context()

La precisión predeterminada para los flotantes es 53 bits. Para


cambiarla usar:
gmpy2.get_context().precision = 100 (cambia precisión a 100 bits)

La precisión en dígitos decimales es igual a la precisión en bits


dividida entre log2(10), aproximadamente 3.3219 .

Al igual que en Python, no existe límite para la cantidad de dígitos


de números enteros.

El contexto se puede cambiar localmente dentro de un programa.

Para convertir o declarar un número se usan las funciones


gmpy2.mpfr para flotantes, gmpy2.mpz para enteros, gmpy2.mpq para
racionales y gmpy2.mpc para complejos.

Ejemplos:
entero= gmpy2.mpz("1234567890123456789012345678901234567890")
entero  mpz(1234567890123456789012345678901234567890)

flotante= gmpy2.mpfr("1234567890123456789012345678901234567890")
flotante  mpfr('1.234567890123456789012345678901e+39',100)

flotante= gmpy2.mpfr("3.141592")
flotante  mpfr(' 3.1415920000000000000000000000003',100)

flotante= gmpy2.mpfr(3.141592)
flotante  mpfr(' 3.1415920000000001621742740098853',100)

racional= gmpy2.mpq(str(3.141592))
racional  mpq(392699,125000)

racional= gmpy2.mpq(3.141592)
racional  mpq(3537118140137533,1125899906842624)

complejo=gmpy2.mpc(3+5j)
complejo  mpc('3.0+5.0j',(100,100))

Es conveniente pasar siempre los números en el argumento como cadena


de caracteres, para que la conversión se realice con la precisión
establecida. Para ello se deben usar comillas o la función str.
En el caso de mpz, para enteros, el resultado es igual si se dan como
números o como caracteres.

Conversión de racional a flotante y entero:


gmpy2.mpfr(racional)  mpfr('3.1415920000000000000000000000003',100)
gmpy2.mpz(racional)  mpz(3)

Notar que para los flotantes siempre indica la precisión en bits

División de dos números:


gmpy2.div(2,3)  mpz(0)
gmpy2.div(2.,3)  mpfr('0.66666666666666666666666666666693',100)
En el primer caso, considera que ambos números son enteros y realiza
una división entera, truncando los decimales.
En el segundo caso, el punto después del 2 hace que lo interprete
como flotante y por ello realiza la división en punto flotante.

gmpy2.mpz(2)/gmpy2.mpz(3) 
mpfr('0.66666666666666666666666666666693',100)
Aquí Python reconoce que los números son objetos clase mpz y para el
operador de división (que es un método) utiliza el de gmpy2 y no el
interno predeterminado.
Si se desea que realice la operación división entera, usar el
operador //:
gmpy2.mpz(2)//gmpy2.mpz(3)  mpz(0)

gmpy2.mpz(2)+gmpy2.mpz(3)  mpz(5)

gmpy2.mpz(2)**gmpy2.mpz(3)  mpz(8)

Todas estas operaciones resultarán en entero, aunque se pongan puntos


o decimales en los argumentos porque se están usando las funciones
mpz en ambos términos y los operandos serán siempre enteros.
En cambio:
gmpy2.mpz(2) + gmpy2.mpfr(3.)  mpfr('5.0',100)
resulta en real porque el segundo operando es real

Si uno de los términos en una operación es de precisión múltiple, el


resultado será de precisión múltiple:
gmpy2.mpz(2.) + 3.  mpfr('5.0',100)

Los operadores: +, -, *, /, // se pueden reemplazar por las funciones


de gmpy2: add, sub, mul, div y divexact, respectivamente.

Por ejemplo:
gmpy2.mul(2,3)  mpz(6)

El operador ** se puede reemplazar directamente por la función de


Python pow con argumentos objetos clase mpz, mpq, mpfr y mpc
Ejemplo:
pow(gmpy2.mpz(2),gmpy2.mpz(3))  mpz(8)

Números complejos
Se convierten y declaran con la función mpc:
gmpy2.sqrt(gmpy2.mpc(-1+1j)) 
mpc('0.45508986056222734130435775782255+1.098684113467809966039801195
2408j',(100,100))

Nota: gmpy2 sólo utiliza j para indicar unidad imaginaria

Si el argumento es real y el resultado de una función es complejo, el


resultado es nan. No hace conversión directa a complejo como Octave,
pero este comportamiento se puede cambiar en las opciones de
contexto.
gmpy2.sqrt(-4)  mpfr('nan')

gmpy2.sqrt(gmpy2.mpfr(-4))  mpfr('nan')
gmpy2.sqrt(gmpy2.mpc(-4))  mpc('0.0+2.0j',(100,100))

pow(gmpy2.mpc(-4),0.5) ))  mpc('0.0+2.0j',(100,100))

Permitir resultados complejos directamente:


gmpy2.get_context().allow_complex = True
gmpy2.sqrt(-4)  mpc('0.0+2.0j',(100,100))

También podría gustarte