Python Resumen

El Zen de Python


In [1]:
import this


The Zen of Python, by Tim Peters

Beautiful is better than ugly.
Explicit is better than implicit.
Simple is better than complex.
Complex is better than complicated.
Flat is better than nested.
Sparse is better than dense.
Readability counts.
Special cases aren't special enough to break the rules.
Although practicality beats purity.
Errors should never pass silently.
Unless explicitly silenced.
In the face of ambiguity, refuse the temptation to guess.
There should be one-- and preferably only one --obvious way to do it.
Although that way may not be obvious at first unless you're Dutch.
Now is better than never.
Although never is often better than *right* now.
If the implementation is hard to explain, it's a bad idea.
If the implementation is easy to explain, it may be a good idea.
Namespaces are one honking great idea -- let's do more of those!

Tipos de datos(Python puro)

Entero


In [6]:
a = 37

In [7]:
type(a)


Out[7]:
int

Float


In [8]:
b = 37.02020

In [9]:
type(b)


Out[9]:
float

Numero Complejo


In [10]:
c = 1+2j

In [11]:
type(c)


Out[11]:
complex

tupla

Como caracteristica principal a las tuplas no se les puede modificar los elementos que la componen(son inmutables) y su longitud es fija una vez creada

Si quiero accerder a un elemento :

d[indice]

d = (a,b,c) d


In [14]:
print 'el primer elemento de la tupla es:', d[0]


el primer elemento de la tupla es: 37

In [15]:
#lo que no se puede hacer con las tuplas
d[0] = 73


---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-15-fc0d76f7d0ee> in <module>()
      1 #lo que no se puede hacer con las tuplas
----> 2 d[0] = 73

TypeError: 'tuple' object does not support item assignment

In [26]:
#Un metodo útil de las tuplas index nos devuelve el indice donde se encuentra algun valor
d.index(37.0202)


Out[26]:
1

In [29]:
# Recorrer una tupla
for item in xrange(len(d)):
    print d[item]


37
37.0202
(1+2j)

Diccionarios

Los diccionarios, deben su nombre a que son colecciones que relacionan una clave y un valor

El primer valor se trata de la clave y el segundo del valor asociado a la clave. Como clave podemos utilizar cualquier valor inmutable: podríamos usar números, cadenas, booleanos, tuplas, ... pero no listas o diccionarios, dado que son mutables


In [31]:
d = {'Nombre':'Pablo','Apellido':'Lovato','Carrera':'IACI','DNI':37.000}

In [32]:
d['DNI']


Out[32]:
37.0

In [34]:
d['Nombre'] = 'Pappo'

In [35]:
d


Out[35]:
{'Apellido': 'Lovato', 'Carrera': 'IACI', 'DNI': 37.0, 'Nombre': 'Pappo'}

Listas

La lista es un tipo de colección ordenada. Sería equivalente a lo que en otros lenguajes se conoce por arrays, o vectores. Pueden contener cualquier tipo de dato: numeros, cadenas, booleanos y tambien listas¡¡. Nosotros vamos a utilizar las listas de Numpy porque son muuucho más rápidas computacionalmente


In [39]:
l = [1,'uno',1+1j]
l


Out[39]:
[1, 'uno', (1+1j)]

In [41]:
# Podemos acceder a los elementos como en las tuplas y asignar valores(Tener en cuenta que los indices comienzan en cero¡¡¡)
l[0]


Out[41]:
1

In [43]:
# Asigno al último elemento la palabra Python
l[-1] = 'Python'
l


Out[43]:
[1, 'uno', 'Python']

Numpy

Biblioteca(modulo) numérico de Python

  • Arrays multimensionales (ndarray)
  • Más cercano al hardware(numéricamente más eficiente)
  • Designado para aplicaciones científicas
  • Utiliza memoria de manera más eficiente
  • Todos los modulos cientificos lo utilizan como tipo de dato básico(Opencv a partir de Opencv2¡¡¡¡)

Under the hood: la dispocisión de memoria en un numpy array es :

bloque de memoria + esquema de indexado + descriptor del tipo de dato

  • datos planos
  • como alocar elementos
  • como interpretar elementos


In [44]:
#Importamos el modulo numpy con el alias np
import numpy as np

In [45]:
#Creo un array 
a = np.array([1,0,0])
a


Out[45]:
array([1, 0, 0])

In [46]:
type(a)


Out[46]:
numpy.ndarray

Python posee por defecto un tipo de datos que se asemeja(listas), pero es numéricamente ineficiente


In [47]:
#Ejemplo creo una lista de Python de 0 a 1000 y calculo el cuadrado de cada elemento
L = range(1000)

In [48]:
%%timeit
#las expresiones que tienen %% son funciones especiales de Ipython por ejemplo %%timeit mide el tiempo de procesamiento
[i**2 for i in L]


10000 loops, best of 3: 87.6 µs per loop

In [49]:
#Ahora hago lo mismo con Numpy
a = np.arange(1000)

In [50]:
%%timeit

a**2


100000 loops, best of 3: 3.18 µs per loop

In [51]:
print 'Numpy es '
print  87/3.16
print 'veces mas rapido'


Numpy es 
27.5316455696
veces mas rapido

Caracteristicas y utilidades principales:


In [52]:
#Creando arrays

a = np.array([1,1,1]) # 1D
b = np.array([[1,1,1],[1,1,1]]) #2d (Matrix)
c = np.array([[[1,1,1],[1,1,1],[1,1,1]]]) #3D (Tensor...)

In [53]:
print a.shape
print b.shape
print c.shape


(3,)
(2, 3)
(1, 3, 3)

In [54]:
#Podemos crear arrays predeterminados con funciones muy utiles

a = np.arange(10) # un array de enteros 0 a 10(no lo incluye) 
a


Out[54]:
array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])

In [55]:
# Array de 1 a 9 con paso 2
b = np.arange(1, 9, 2)
b


Out[55]:
array([1, 3, 5, 7])

In [56]:
#Como en Matlab
a = np.ones((3,3))
a


Out[56]:
array([[ 1.,  1.,  1.],
       [ 1.,  1.,  1.],
       [ 1.,  1.,  1.]])

In [57]:
b = np.zeros((5,5))
b


Out[57]:
array([[ 0.,  0.,  0.,  0.,  0.],
       [ 0.,  0.,  0.,  0.,  0.],
       [ 0.,  0.,  0.,  0.,  0.],
       [ 0.,  0.,  0.,  0.,  0.],
       [ 0.,  0.,  0.,  0.,  0.]])

In [58]:
c = np.eye(10)
c


Out[58]:
array([[ 1.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.],
       [ 0.,  1.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.],
       [ 0.,  0.,  1.,  0.,  0.,  0.,  0.,  0.,  0.,  0.],
       [ 0.,  0.,  0.,  1.,  0.,  0.,  0.,  0.,  0.,  0.],
       [ 0.,  0.,  0.,  0.,  1.,  0.,  0.,  0.,  0.,  0.],
       [ 0.,  0.,  0.,  0.,  0.,  1.,  0.,  0.,  0.,  0.],
       [ 0.,  0.,  0.,  0.,  0.,  0.,  1.,  0.,  0.,  0.],
       [ 0.,  0.,  0.,  0.,  0.,  0.,  0.,  1.,  0.,  0.],
       [ 0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  1.,  0.],
       [ 0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  1.]])

In [59]:
d = np.diag(np.array([1, 2, 3, 4]))
d


Out[59]:
array([[1, 0, 0, 0],
       [0, 2, 0, 0],
       [0, 0, 3, 0],
       [0, 0, 0, 4]])

In [60]:
#Complex numbers
e = np.array([1+2j, 3+4j, 5+6*1j])
e


Out[60]:
array([ 1.+2.j,  3.+4.j,  5.+6.j])

In [61]:
#boolean
e = np.array([True, False, False, True])
e


Out[61]:
array([ True, False, False,  True], dtype=bool)

In [62]:
#String
f = np.array(['Bonjour', 'Hello', 'Hallo',])
f


Out[62]:
array(['Bonjour', 'Hello', 'Hallo'], 
      dtype='|S7')

Indexing and slicing

Los items de un array pueden accederse de una manera natural como en Matlab(hay que tener en cuenta que los indices comienzan en 0)


In [63]:
a = np.arange(10)
a


Out[63]:
array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])

In [64]:
# Slicing [comienzo:final:paso]
# Los tres no son necesarios explicitamente ya que por default comienzo=0, final=[-1] y el paso=1

a[2:8:2]


Out[64]:
array([2, 4, 6])

In [65]:
a[::4] # solo cambiamos el paso


Out[65]:
array([0, 4, 8])

Fancy indexing

Hay más maneras de indexar y asignar


In [66]:
np.random.seed(3)
a = np.random.random_integers(0, 20, 15)
a


Out[66]:
array([10,  3,  8,  0, 19, 10, 11,  9, 10,  6,  0, 20, 12,  7, 14])

In [67]:
#pido una condicion a los elementos del array la salida es un nuevo array booleano
(a % 3 == 0)


Out[67]:
array([False,  True, False,  True, False, False, False,  True, False,
        True,  True, False,  True, False, False], dtype=bool)

In [68]:
#puedo indexar y asignar con este array como mascara
mask = (a % 3 == 0)
a_multiplos_3 = a[mask]
a_multiplos_3


Out[68]:
array([ 3,  0,  9,  6,  0, 12])

In [69]:
#Puedo indexar y asignar al mismo tiempo
a[mask] = -1
a


Out[69]:
array([10, -1,  8, -1, 19, 10, 11, -1, 10, -1, -1, 20, -1,  7, 14])

Funciones

Las funciones se definen con la palabra reservada def, la estructura es la siguiente:

def nombre_funcion(parametro1, parametro2):
    """Docstring"""
    operaciones

    return objetos

Ejemplo:


In [38]:
def power(number, potencia):
    """Funcion para elevar a una potencia a un numero"""
    
    return number**potencia

In [39]:
power(2+1j,10)


Out[39]:
(-237-3116j)

Una funcion puede devolver varios valores, que los puedo encapsular en una tupla:


In [78]:
def ndarray_shape_type(ndarray):
    rows, cols = ndarray.shape
    
    return rows, cols, ndarray.sum()

In [79]:
a = np.random.random((3,3))

In [80]:
info = ndarray_shape_type(a)
info


Out[80]:
(3, 3, 4.4680994807263508)

In [ ]: