27/04/2013

Descubriendo trending topics de twitter con python-twitter.

Recuerdo la presentación de Efrain en el PyDay en Mérida, donde hablo de la librería tweepy (acá artículo de Efrain sobre el tema) que permite acceder a una cuenta de twitter, actualizar estado entre otras cosas.

Con el auge de twitter como red social en el país me dispuse a probar otra librería de python para twitter llamada python-twitter, la documentación de la librería se puede acceder desde acá. Existe una serie de ejemplos de como usar la librería python-twitter en  github.

Instalar la librería de twitter:
Se usará el comando easy_install o pip como root:
easy_install twitter
ó
pip install twitter

El código que se muestra a continuación lista el ID de los Países, el número ID de cada País. El código original lo pueden ver en el siguiente enlace:
Se ejecuta python:

(python2.7)ernesto@jewel:~/prueba$ python

Python 2.7.3 (default, Jan  2 2013, 16:53:07) 

[GCC 4.7.2] on linux2

Type "help", "copyright", "credits" or "license" for more information.

>>>

Se importa el módulo python-twitter:
>>> import twitter


Se instancia la clase Twitter pasando el dominio (el url de la api de twitter) y la versión del api que en este caso es la versión 1:
>>> twitter_api = twitter.Twitter(domain="api.twitter.com", api_version='1')

Se captura los trends disponibles:
>>> trends1 = twitter_api.trends.available()

Se lista los ID de los Países:
>>> for location in trends1:
...     name = location["name"].encode('ascii', 'replace')
...     print "(%d) %s" % (location["woeid"], name)
... 
(1) Worldwide
(2972) Winnipeg
(3369) Ottawa
(3444) Quebec
(3534) Montreal
(4118) Toronto
(8676) Edmonton
(8775) Calgary
(9807) Vancouver
(12723) Birmingham
(13911) Brighton
(13963) Bristol
(15127) Cardiff
(19344) Edinburgh
(21125) Glasgow
(26042) Leeds
(26062) Leicester
(26734) Liverpool
(28218) Manchester
(30079) Newcastle
(30720) Nottingham
(32452) Portsmouth
(34503) Sheffield
(44418) London
(44544) Belfast
(76456) Santo Domingo
(116545) Mexico City
(124162) Guadalajara
(131068) Le?n
(134047) Monterrey
(137612) Puebla
(149361) Tijuana
(332471) Mendoza
(349859) Santiago
(349860) Concepcion
(349861) Valparaiso
(368148) Bogot?
(395269) Caracas
(395270) Maracaibo
(395272) Valencia
(418440) Lima
(455819) Bras?lia
(455820) Bel?m
(455821) Belo Horizonte
(455822) Curitiba
(455823) Porto Alegre
(455824) Recife
(455825) Rio de Janeiro
(455826) Salvador
(455827) S?o Paulo
(455828) Campinas
(455830) Fortaleza
(455831) Goi?nia
(455833) Manaus
(455834) S?o Lu?s
(455867) Guarulhos
(466861) C?rdoba
(466862) Rosario
(468382) Barquisimeto
(468739) Buenos Aires
(560743) Dublin
(580778) Bordeaux
(608105) Lille
(609125) Lyon
(610264) Marseille
(612977) Montpellier
(613858) Nantes
(615702) Paris
(619163) Rennes
(627791) Strasbourg
(628886) Toulouse
(638242) Berlin
(641142) Bremen
(645458) Dortmund
(645686) Dresden
(646099) Dusseldorf
(648820) Essen
(650272) Frankfurt
(656958) Hamburg
(667931) Cologne
(671072) Leipzig
(676757) Munich
(698064) Stuttgart
(718345) Milan
(719258) Naples
(721943) Rome
(725003) Turin
(726874) Den Haag
(727232) Amsterdam
(733075) Rotterdam
(753692) Barcelona
(766273) Madrid
(766356) Malaga
(774508) Seville
(776688) Valencia
(779063) Zaragoza
(906057) Stockholm
(1030077) Bekasi
(1044316) Surabaya
(1047180) Bandung
(1047378) Jakarta
(1062617) Singapore
(1098081) Perth
(1099805) Adelaide
(1100661) Brisbane
(1100968) Canberra
(1101597) Darwin
(1103816) Melbourne
(1105779) Sydney
(1110809) Kitakyushu
(1117034) Chiba
(1117099) Fukuoka
(1117227) Hiroshima
(1117502) Kawasaki
(1117545) Kobe
(1117817) Nagoya
(1118108) Sapporo
(1118129) Sendai
(1118285) Takamatsu
(1118370) Tokyo
(1118550) Yokohama
(1132447) Busan
(1132466) Daegu
(1132481) Gwangju
(1132496) Incheon
(1132567) Suwon
(1132578) Ulsan
(1132599) Seoul
(1154726) Klang
(1154781) Kuala Lumpur
(1167715) Calocan
(1199136) Davao City
(1199477) Manila
(1199682) Quezon City
(1398823) Lagos
(1582504) Johannesburg
(2077746) Samara
(2112237) Yekaterinburg
(2122265) Moscow
(2122471) Nizhny Novgorod
(2122541) Novosibirsk
(2122641) Omsk
(2123260) Saint Petersburg
(2282863) Nagpur
(2295377) Lucknow
(2295378) Kanpur
(2295386) Kolkata
(2295388) Amritsar
(2295401) Jaipur
(2295402) Ahmedabad
(2295408) Indore
(2295411) Mumbai
(2295412) Pune
(2295414) Hyderabad
(2295420) Bangalore
(2295424) Chennai
(2343678) Adana
(2343732) Ankara
(2343843) Bursa
(2344116) Istanbul
(2344117) Izmir
(2345896) Okinawa
(2345975) Daejeon
(2357024) Atlanta
(2357536) Austin
(2358820) Baltimore
(2359991) Baton Rouge
(2364559) Birmingham
(2367105) Boston
(2378426) Charlotte
(2379574) Chicago
(2380358) Cincinnati
(2381475) Cleveland
(2383660) Columbus
(2388929) Dallas-Ft. Worth
(2391279) Denver
(2391585) Detroit
(2414469) Greensboro
(2418046) Harrisburg
(2424766) Houston
(2427032) Indianapolis
(2428184) Jackson
(2436704) Las Vegas
(2442047) Los Angeles
(2449323) Memphis
(2450022) Miami
(2451822) Milwaukee
(2452078) Minneapolis
(2457170) Nashville
(2458410) New Haven
(2458833) New Orleans
(2459115) New York
(2460389) Norfolk
(2466256) Orlando
(2471217) Philadelphia
(2471390) Phoenix
(2473224) Pittsburgh
(2475687) Portland
(2477058) Providence
(2478307) Raleigh
(2480894) Richmond
(2486340) Sacramento
(2486982) St. Louis
(2487610) Salt Lake City
(2487796) San Antonio
(2487889) San Diego
(2487956) San Francisco
(2490383) Seattle
(2503713) Tallahassee
(2503863) Tampa
(2514815) Washington
(15015370) Osaka
(15015372) Kyoto
(20070458) Delhi
(23424738) United Arab Emirates
(23424747) Argentina
(23424748) Australia
(23424768) Brazil
(23424775) Canada
(23424782) Chile
(23424787) Colombia
(23424800) Dominican Republic
(23424801) Ecuador
(23424803) Ireland
(23424819) France
(23424829) Germany
(23424834) Guatemala
(23424846) Indonesia
(23424848) India
(23424853) Italy
(23424856) Japan
(23424868) Korea
(23424900) Mexico
(23424901) Malaysia
(23424908) Nigeria
(23424909) Netherlands
(23424916) New Zealand
(23424919) Peru
(23424922) Pakistan
(23424934) Philippines
(23424936) Russia
(23424942) South Africa
(23424948) Singapore
(23424950) Spain
(23424954) Sweden
(23424969) Turkey
(23424975) United Kingdom
(23424977) United States
(23424982) Venezuela
(56013632) Petaling
(56013645) Hulu Langat


EL ID 1 es para listar los trending topics  mundial, para Venezuela se tiene el ID 23424982, se resalta en negrita los IDs de las ciudades de Venezuela. 

Ahora se va a desplegar la lista de trending topic global(1): 
Se define el valor 1 a WOE_ID para capturar el trending topic global, se instancia la clase Twitter con el dominio api.twitter.com y se define la versión del api como la versión 1. A continuación se captura los trending topic, se muestra los 10 tópicos del mundo.
>>>WORLD_WOE_ID = 1
>>> twitter_api = twitter.Twitter(domain="api.twitter.com", api_version='1')
>>> world_trends = twitter_api.trends._(WORLD_WOE_ID)
>>> trends = world_trends()
>>> for i in range(10):
...     print trends[0]['trends'][i][u'name']
... 
#ILoveCheese
#CaprilesVenezuelayELMUNDOestácontigo
#MiMamáDice
#VamosMaravilla
#AJuicioCaprilesAsesino
Sara McMann
Rene de Calle 13
Sheila Gaff
RDMA
Rene

Al cambiar el valor de la variable WORLD_WOE_ID a la de Venezuela (23424982) se tiene:
>>> WORLD_WOE_ID = 23424982
>>> twitter_api = twitter.Twitter(domain="api.twitter.com", api_version='1')
>>> world_trends = twitter_api.trends._(WORLD_WOE_ID)
>>> trends = world_trends()
>>> for i in range(10):
...     print trends[0]['trends'][i][u'name']
... 
#CaprilesVenezuelayELMUNDOestácontigo
#AJuicioCaprilesAsesino
#MiMamáDice
#MeArrechoCuando
#QueVivan
Feliz Día del Diseñador Gráfico
Estuvimos 5
Dayana Mendoza
Omar Borkan Al Gala
Antonio Rivero


Para el caso de Valencia (395272):
>>> WORLD_WOE_ID = 395272
>>> twitter_api = twitter.Twitter(domain="api.twitter.com", api_version='1')
>>> world_trends = twitter_api.trends._(WORLD_WOE_ID)
>>> trends = world_trends()
>>> for i in range(10):
...     print trends[0]['trends'][i][u'name']
... 
#CaprilesVenezuelayELMUNDOestácontigo
#AJuicioCaprilesAsesino
#MeArrechoCuando
#MiMamáDice
Omar Borkan Al Gala
#TROPA
Feliz Día del Diseñador Gráfico
Estuvimos 5
Dayana Mendoza
Antonio Rivero

De esta forma se puede listar los 10 tópicos  según el País o ciudad utilizando Python. 

22/04/2013

Descubrir equipos en una Red Local con Python (ipcalc y scapy).

Si se tiene una red con asignación abierta de IPs, la administración se hace algo complicada, así que se necesita tener un registro de la asignación de IPs a los equipos de la red local.

Una amiga administradora hizo un registro con una herramienta propietaria en Windows. Recordé la librería de python ipcalc que facilita el cálculo de direcciones IP y redes (un artículo de su uso acá).

Además existe la librería o herramienta scapy, el cual permite capturar y modificar paquetes de red (la documentación se puede revisar en el siguiente enlace).

Una alternativa es usar los comandos ping y arp por medio de python con el módulo commands; es preferible usar scapy que permite descubrir la dirección MAC de los equipos que tienen asignado las IPs.

Así que por un lado se usa ipcalc para definir el rango de la red según la mascara y luego con scapy se descubre las direcciones MAC.

A continuación el código que devuelve la dirección MAC de cada IP utilizada en la red:

#!/usr/bin/env python



#Se importa los modulos necesarios.

from ipcalc import IP, Network

from scapy.all import srp,Ether,ARP,conf



#Se desactiva el verbose de la captura y envio de paquetes.



conf.verb=0

#Se genera un ciclo con el rango de IPs dando la RED y la mascara

for ip in Network('192.168.12.128/25'):

    #Se realiza un broadcast de MAC pasando cada IP el cual devuelve la 

    #direccion MAC de la IP consultada.

    ans,unans=srp(Ether(dst="ff:ff:ff:ff:ff:ff")/ARP(pdst=str(ip)),timeout=2)

    for snd,rcv in ans:

        #Se muestra en pantalla la direccion MAC y la direccion IP

        print rcv.sprintf(r"%Ether.src% y %ARP.psrc%")





Al ejecutar el programa se tiene lo siguiente:

ernesto@jewel:~/bin/python$ sudo ./descubrir.py

WARNING: No route found for IPv6 destination :: (no default route?)

00:26:35:c6:93:0d y 192.168.12.130

00:2e:0b:c5:70:3c y 192.168.12.132

00:2e:90:c2:ec:51 y 192.168.12.134

00:50:ca:c1:71:8a y 192.168.12.136

00:32:57:ce:81:e7 y 192.168.12.138

00:2e:90:c4:58:7c y 192.168.12.139

00:2c:25:ce:ae:be y 192.168.12.140

d0:37:88:c4:11:ed y 192.168.12.141

00:2e:90:cc:f5:16 y 192.168.12.142

00:2c:c4:c4:26:28 y 192.168.12.148

40:7a:ab:ce:11:c0 y 192.168.12.150

3c:53:8e:cc:4d:89 y 192.168.12.161

1c:5b:d6:c9:6d:a9 y 192.168.12.169

00:2e:7f:c4:8d:d7 y 192.168.12.170

00:24:c2:c8:23:8d y 192.168.12.172

68:19:ed:c75:44:31 y 192.168.12.174

74:3f:68:c2:91:d6 y 192.168.12.196

00:30:aa:c2:6d:3c y 192.168.12.201

c8:3c:dc:c8:a9:53 y 192.168.12.208

00:34:f2:c5:2f:21 y 192.168.12.211

00:34:f2:cc:2e:d0 y 192.168.12.212

00:34:f2:c5:35:70 y 192.168.12.214

00:34:f2:c3:1a:ee y 192.168.12.215

00:34:f2:c3:1b:4c y 192.168.12.216

00:34:f2:c5:33:49 y 192.168.12.224

00:3c:02:c6:b5:3f y 192.168.12.225

00:3e:90:c8:bb:d6 y 192.168.12.251

Así pues desde Linux y con Python se puede capturar la información de las direcciones MAC de las IPs asignadas con pocas líneas de código.


21/02/2013

Resolución de sistemas de ecuaciones lineales por descomposión QR usando Numpy

En Diciembre se  publicó un artículo donde se explica como resolver sistemas de ecuaciones.

Este artículo se basa de un artículo en Inglés QR descomposition with numpy .

Si se desea averiguar más sobre la descomposición QR se puede consultar a la página de wikipedia ó de la siguiente página.

Las ecuaciones que se usaron son:
3x+9y-10z  =   24
x-6y+4z      =   -4
10x-2y+8z  =  20

Donde Ax = b.
A = [[3 9 -10][1 -6 4][10 -2 8]] y
B  = [[24][-4[[20]]




El código se muestra a continuación:


#!/usr/bin/env python
# -*- coding: utf-8 -*-

from numpy import *


#Se define los valores de la matriz A
A = array([[3,9,-10],[1,-6,4],[10,-2,8]])

Q,R = linalg.qr(A) # qr decomposition of A

#Se definen los valores de la matriz B
b = array([[24],[-4],[20]])


#resolver Ax=b usando la funcion estandar numpy
x = linalg.solve(A,b)


#resolver Ax = b usando Q y R.
y = dot(Q.T,b)
xQR = linalg.solve(R,y) 

print "\nComparacion de Soluciones:"
print x.T,'Ax=b'
print xQR.T,'Rx=y'

Al ejecutar el script se tiene lo siguiente:
python qr.py  Comparacion de Soluciones: [[ 2.99029126  0.40776699 -1.13592233]] Ax=b [[ 2.99029126  0.40776699 -1.13592233]] Rx=y
Como se puede ver, la solución usando la función estándar de numpy y por la descomposición QR generan el mismo resultado.




20/02/2013

Creación de gráfico de burbujas con matplotlib

Los gráficos de burbuja presentan los datos como una serie de burbujas, el tamaño de las cuales es proporcional a la cantidad de datos. 

Un gráfico de este tipo resulta muy efectivo para mostrar el número de productos vendidos en cierta región.

Existe una herramienta que se llama Trendalyzer  desarrollada por la Fundación Gapminder, está herramienta permite convertir series de estadísticas en gráficos interactivos. 

Es Hans Rosling uno de los fundadores de Gapminder quien ha mostrado el potencial de la herramienta.
El siguiente vídeo es una demostración de la herramienta:

Con matplotlib en Python también se pueden crear gráficas de burbuja, el artículo se basa en un artículo en Inglés llamado "How to make Bubble charts with matplotlib". 

Los datos se obtendrán de un archivo csv, estos datos son de estadística del crimen en los Estados Unidos por estado del año 2005. El archivo csv se puede bajar aquí

La información en el archivo csv se tiene de la siguiente forma (se muestra las primeras líneas del archivo):


state,murder,forcible_rape,robbery,aggravated_assault,burglary,larceny_theft,motor_vehicle_theft,population
United States,5.6,31.7,140.7,291.1,726.7,2286.3,416.7,295753151
Alabama,8.2,34.3,141.4,247.8,953.8,2650,288.3,4545049
Alaska,4.8,81.1,80.9,465.1,622.5,2599.1,391,669488
Arizona,7.5,33.8,144.4,327.4,948.4,2965.2,924.4,5974834
Arkansas,6.7,42.9,91.1,386.8,1084.6,2711.2,262.1,2776221
California,6.9,26,176.1,317.3,693.3,1916.5,712.8,35795255



Como se ve la primera línea se tiene el título de cada columna, en la segunda línea se tiene la información total de Estados Unidos y luego se muestra la información por Estado.




Para efectos de programación la primera y segunda línea no son relevantes para la gráfica de burbuja.




A continuación el código del programa:

#!/usr/bin/env python
# -*- coding: utf-8 -*-

from pylab import *
from scipy import *

#Leer los datos desde el archivo csv
#Archivo original
#durl = 'http://datasets.flowingdata.com/crimeRatesByState2005.csv'
#Archivo modificado.
durl = 'http://127.0.0.1/descargas/crimeRatesByState2005-es.csv'
#Se captura los datos del archivo csv.
rdata = genfromtxt(durl,dtype='S8,f,f,f,f,f,f,f,i',delimiter=',')

rdata[0] = zeros(8) # se elimina los titulos 
rdata[1] = zeros(8) # se elimina la estadistica total de estados unidos (2da linea)
x = []
y = []
color = []
area = []

#Se captura los datos de cada fila
for data in rdata:
    x.append(data[1]) # asesinatos
    y.append(data[5]) # robo
    color.append(data[6]) # hurtos
    area.append(sqrt(data[8])) # poblacion
    # graficando las primeras 8 letras del nombre del estado
    text(data[1], data[5],data[0],size=11,horizontalalignment='center')
    

# se crea la grafica
sct = scatter(x, y, c=color, s=area, linewidths=2, edgecolor='w')
sct.set_alpha(0.75)
#Se define los ejes
axis([0,11,200,1280])
#Las etiquetas de cada eje
xlabel('Asesinatos por cada 100.000 habitantes')
ylabel('Robos por cada 100.000 habitantes')
show()

La siguiente figura muestra el resultado de la ejecución del programa:



19/02/2013

Manejar información de un archivo csv con csvkit

El programa csvkit es una herramienta desarrollada en Python que facilita la manipulación de la información contenida en un archivo con formato csv.

Se utilizará como ejemplo los datos de la página data.gov. Los datos que se utilizará son del Departamento de Asuntos de Veteranos de beneficios educativos de los Estatos Unidos (disculpen la traducción) del año 2009.

Es necesario instalar csvkit, en este caso se usa el comando pip de python:
pip install csvkit

Obtener los datos:
mkdir beneficios

cd beneficios 

Bajar archivo 2009.csv con el comando wget:
wget -O 2009.csv -U "Mozilla/5.0 (X11; U; Linux x86_64; en-US) AppleWebKit/534.16 (JHTML, like Gecko) chrome/10.0.648.205 Safari/534.16" http://www.data.gob/download/4029/csv 

Verificar las primeras 5 líneas del archivo:

head -n 5 2009.csv 

State Name,State Abbreviate,Code,Montgomery GI Bill-Active Duty,Montgomery GI Bill- Selective Reserve,Dependents' Educational Assistance,Reserve Educational Assistance Program,Post-Vietnam Era Veteran's Educational Assistance Program,TOTAL,

ALABAMA,AL,01,"6,718","1,728","2,703","1,269",8,"12,426",

ALASKA,AK,02,776,154,166,60,2,"1,158",

ARIZONA,AZ,04,"26,822","2,005","3,137","2,011",11,"33,986",

ARKANSAS,AR,05,"2,061",988,"1,575",886,3,"5,513",

Se puede usar el mismo comando wget para bajar los archivos de los años 2010.csv, 2011.csv y 2012.csv.

Obtener la información de las columnas con csvcut:

csvcut -n 2009.csv

  1: State Name

  2: State Abbreviate

  3: Code

  4: Montgomery GI Bill-Active Duty

  5: Montgomery GI Bill- Selective Reserve

  6: Dependents' Educational Assistance

  7: Reserve Educational Assistance Program

  8: Post-Vietnam Era Veteran's Educational Assistance Program

  9: TOTAL

 10: 

Como se puede observar, el archivo csv maneja 9 columnas. 

Con el comando csvcut se puede obtener información entre la fila 2 y 3 (State Abbreviate y Code), sólo se desea mostrar las primeras 5 líneas del archivo: 
csvcut -c 2,3 2009.csv | head -n 5
State Abbreviate,Code
AL,01
AK,02
AZ,04
AR,05


Se puede también manejar estadisticas bajo demanda con csvstat. Se genera la estadistica de la información de las columnas 1,4,9 y 10. Para este caso se utiliza csvcut y se pasa la información a csvstat:

csvcut -c 1,4,9,10 2009.csv | csvstat
  1. State Name
<type 'unicode'>
Nulls: True
Unique values: 52
Max length: 17
  2. Montgomery GI Bill-Active Duty
<type 'int'>
Nulls: True
Min: 435
Max: 34942
Sum: 325723
Mean: 6263.90384615
Median: 3548.0
Standard Deviation: 7537.86225373
Unique values: 52
  3. TOTAL
<type 'int'>
Nulls: True
Min: 768
Max: 46897
Sum: 506914
Mean: 9748.34615385
Median: 6520.0
Standard Deviation: 10070.4022127
Unique values: 52
  4. _unnamed
<type 'NoneType'>
Nulls: True
Values: 




Se puede realizar busquedas por filas con csvgrep. En este caso la información total del Estado de Illinois:

csvcut -c 1,"TOTAL" 2009.csv | csvgrep -c 1 -m ILLINOIS

State Name,TOTAL

ILLINOIS,"21,964"

Voltear orden de las columnas con csvcut: 
csvcut -c 9,1 2009.csv | head -n 5
TOTAL,State Name
"12,426",ALABAMA
"1,158",ALASKA
"33,986",ARIZONA
"5,513",ARKANSAS
En este caso se cambia el orden de las columnas al decirle a csvcut el orden de las columnas. 

Ordenar con csvsort: 
csvcut -c 9,1 2009.csv | csvsort -r | head -n 5
TOTAL,State Name
46897,CALIFORNIA
40402,TEXAS
36394,FLORIDA
33986,ARIZONA

Se puede dar un formato para que sea legible la información con csvlook:
csvcut -c 9,1 2009.csv | csvsort -r -l | csvlook
|--------------+-------+--------------------|
|  line_number | TOTAL | State Name         |
|--------------+-------+--------------------|
|  1           | 46897 | CALIFORNIA         |
|  2           | 40402 | TEXAS              |
|  3           | 36394 | FLORIDA            |
|  4           | 33986 | ARIZONA            |
|  5           | 21964 | ILLINOIS           |
|  6           | 20541 | VIRGINIA           |
|  7           | 18236 | GEORGIA            |
|  8           | 15730 | NORTH CAROLINA     |
|  9           | 13967 | NEW YORK           |
|  10          | 13962 | MISSOURI           |
|  11          | 13614 | COLORADO           |
|  12          | 13314 | OHIO               |
|  13          | 13011 | PENNSYLVANIA       |
|  14          | 12426 | ALABAMA            |
|  15          | 11492 | WASHINGTON         |
|  16          | 10085 | MARYLAND           |
|  17          | 9791  | MINNESOTA          |
|  18          | 9344  | MICHIGAN           |
|  19          | 9206  | OKLAHOMA           |
|  20          | 9013  | IOWA               |
|  21          | 8840  | WEST VIRGINIA      |
|  22          | 8757  | TENNESSEE          |
|  23          | 8081  | WISCONSIN          |
|  24          | 7872  | SOUTH CAROLINA     |
|  25          | 7809  | INDIANA            |
|  26          | 6652  | LOUISIANA          |
|  27          | 6388  | KENTUCKY           |
|  28          | 6009  | MASSACHUSETTS      |
|  29          | 5870  | OREGON             |
|  30          | 5513  | ARKANSAS           |
|  31          | 5511  | NEW JERSEY         |
|  32          | 5416  | NEBRASKA           |
|  33          | 5345  | UTAH               |
|  34          | 4947  | KANSAS             |
|  35          | 4551  | NEW MEXICO         |
|  36          | 4424  | PUERTO RICO        |
|  37          | 4299  | MISSISSIPPI        |
|  38          | 3728  | NEVADA             |
|  39          | 2997  | CONNECTICUT        |
|  40          | 2751  | IDAHO              |
|  41          | 2521  | HAWAII             |
|  42          | 1992  | SOUTH DAKOTA       |
|  43          | 1920  | MAINE              |
|  44          | 1795  | MONTANA            |
|  45          | 1778  | NORTH DAKOTA       |
|  46          | 1326  | NEW HAMPSHIRE      |
|  47          | 1175  | RHODE ISLAND       |
|  48          | 1158  | ALASKA             |
|  49          | 1145  | DELAWARE           |
|  50          | 1117  | WYOMING            |
|  51          | 1084  | DIST. OF COLUMBIA  |
|  52          | 768   | VERMONT            |
|  53          |       |                    |
|--------------+-------+--------------------|


Para finalizar se puede salvar el trabajo en un nuevo archivo csv:
csvcut -c 9,1 2009.csv | csvsort -r -l > 2009_ranking.csv

Si se desea aprender más de la herramienta csvkit se puede revisar la página de la documentación

En próximo artículo se mostrará como usar csvkit desde un programa en Python.

Teorema de muestreo explicado con numpy

El teorema demuestra que la reconstrucción exacta de una señal periódica continua en banda base a partir de sus muestras, es matemáticamente posible si la señal está limitada en banda y la tasa de muestreo es superior al doble de su ancho de banda. 
En el artículo se mostrará una tasa de muestreo a diferentes frecuencias, desde el valor doble a la frecuencia base, luego a un valor menor.

Algo más de teoría:
El teorema de muestreo de una señal continua que x (t) limitada en banda a B Hz pueden ser recuperados de sus muestras x [n] = x (n * T), donde n es un número entero, si T es mayor que o igual a 1 / (2B) sin pérdida de ninguna información. Y llamamos 2B la tasa de Nyquist.

El muestreo a una tasa inferior a la tasa de Nyquist se denomina submuestreo, se produce el efecto aliasing.

Si se desea más información sobre el Teorema de Muestreo se puede consultar a wikipedia.

Este artículo se basa en un artículo en Inglés "The sampling theorem explained with numpy" .

El código se muestra a continuación:


#!/usr/bin/env python



#De numpy se importa lo necesario para graficar la

#funcion seno

from numpy import linspace,sin,cos,pi,ceil,floor,arange



#De pylab se importa plot, show y axis. Lo necesario para crear

#la grafica

from pylab import plot,show,axis





#Muestreo de una seganl de ancho de banda 40 hz

# con velocidad de muestreo de 80 Hz

f = 40;  # Hz

#Tiempo minimo y maximo

tmin = -0.3;

tmax = 0.3;

#Se define el tiempo de la segnal.

t = linspace(tmin, tmax, 400);

#Se define la segnal de muestreo

x = cos(2*pi*t) + cos(2*pi*f*t)

#Se grafica el tiempo y la segnal.

plot(t, x)



# sampling the signal with a sampling rate of 80 Hz

# in this case, we are using the Nyquist rate.

#Muestreo de la segnal con una velocidad de muestreo de 80 Hz.

#Periodo de muestreo

T = 1/80.0;

#Tiempo minimo

nmin = ceil(tmin / T);

#Tiempo maximo

nmax = floor(tmax / T);

#Tiempo de la segnal.

n = arange(nmin,nmax);

#Segnal a la velocidad de muestreo

x1 = cos(2*pi*n*T) + cos(2*pi*f*n*T);

#Se grafica la segnal.

plot(n*T, x1, 'bo')



#Muestreo de la segnal con una velocidad de muestreo de 35Hz.

#Note que 35Hz esta por debajo de la velocidad de Nyquist.

T = 1/35.0;

nmin = ceil(tmin / T);

nmax = floor(tmax / T);

n = arange(nmin,nmax);

x2 = cos(2*pi*n*T) + cos(2*pi*f*n*T);

plot(n*T, x2, '-r.',markersize=15)







axis([-0.3, 0.3, -1.5, 2.3])

show()

La gráfica generada es la siguiente:

Con puntos azules se tiene el muestreo a 80Hz, con puntos rojos se tiene el muestreo a 35 Hz, se nota que el muestreo a 80 Hz es suficiente para capturar la oscilación de la señal.

En la siguiente gráfica se tiene un muestreo a 10 Hz que está por debajo de la frecuencia base de la señal (40 Hz).

Ahora se muestra la frecuencia de muestreo a 20 Hz:

Para terminar se muestra la frecuencia de muestreo a 30 Hz:

Para terminar se muestra la gráfica a una frecuencia de muestreo de 320 Hz:
Como puede notarse, mientras menor es la frecuencia de muestreo con respecto a la frecuencia base de la señal no se puede generar la señal original a partir de la muestra, mientras se va a aumentando la señal hasta llegar a la frecuencia base, se nota que se tiene más muestras para dicha recuperación pero sigue sin ser suficiente, es a partir del doble de la frecuencia base que la muestra puede ser generada.


18/02/2013

Encontrar el mínimo de una función usando fmin de scipy

Este artículo muestra como se encuentra el valor mínimo de una función con la función fmin de scipy.

El artículo es una versión en Español del artículo en Inglés "How to find the minimum of a function using fmin from scipy".

El código se muestra a continuación:


#!/usr/bin/env python



#Importar numpy,pylab y la función fmin de scipy.optimize.

import numpy

import pylab

from scipy.optimize import fmin



# Se define la funcion a partir de lambda.

rsinc = lambda x: -1 * numpy.sin(x)/x



#Se define un valor x0 de -5.

x0 = -5

#Se calcula el valor minimo de la funcion en el punto x0

xmin0 = fmin(rsinc,x0)



#Se define el punto x1 con valor -4

x1 = -4

#Se calcula el valor minimo de la funcion en el punto x1

xmin1 = fmin(rsinc,x1)



# se grafica la funcion.

x = numpy.linspace(-15,15,100)

y = rsinc(x)

pylab.plot(x,y)



#Se define el punto x0 en la grafica de la funcion

pylab.plot(x0,rsinc(x0),'bd',xmin0,rsinc(xmin0),'bo')

#Se define el punto x1 en la grafica de la funcion

pylab.plot(x1,rsinc(x1),'rd',xmin1,rsinc(xmin1),'ro')

pylab.axis([-15,15,-1.3,0.3])

pylab.show()



La figura a continuación muestra la gráfica de la función:

El punto azul es el mínimo encontrado al inicio desde diamante azul  (x= -5), el punto rojo es el mínimo encontrado iniciando desde diamante rojo. Este punto es el mínimo global encontrado en la función.

Además de la gráfica se genera la siguiente salida que genera la función fmin:


Optimization terminated successfully.
         Current function value: -0.128375
         Iterations: 18
         Function evaluations: 36
Optimization terminated successfully.
         Current function value: -1.000000
         Iterations: 19
         Function evaluations: 38



15/02/2013

Graficar la intercepción de 2 funciones

En este artículo se explica como encontrar la intercepción de 2 funciones, en este caso una función senoidal con una cosenoidal.

El artículo se basa en uno en Inglés que se llama "How to find the intersection of two functions".

La gráfica mostrará la intercepción de las funciones sin(x) y cos(x) desde el valor inicial de x igual a cero. Se utilizará la función fsolve la cual devuelve la raíz de una ecuación (no lineal ) definida por func(x) = 0.

A continuación se muestra el código:


#!/usr/bin/env python



from scipy.optimize import fsolve

#Importar pylab

import pylab

#Importar numpy

import numpy



#Se define la funcion que calcula la intercepcion

#de 2 funciones.

def EncontrarIntercepcion(fun1,fun2,x0):
    #Se usa la función lambda de la diferencia de ambas funciones con
    #valor inicial x0
    return fsolve(lambda x : fun1(x) - fun2(x),x0)









if __name__ == '__main__':

    #se calcula el resultado de la intercepcion de 2 funciones

    #sin y cos con valor inicial de 0.

    resultado = EncontrarInterseccion(numpy.sin,numpy.cos,0.0)

    #se genera el rango de -2 a 2.

    x = numpy.linspace(-2,2,50)

    #Se genera la grafica, 

    pylab.plot(x,numpy.sin(x),x,numpy.cos(x),result,numpy.sin(result),'ro')

    #se muestra la grafica.

    pylab.show()

La gráfica se muestra a continuación:
La función seno se encuentra en color azul,la gráfica del coseno en color verde y la intercepción es un punto de color rojo.

Enhanced by Zemanta

14/02/2013

Encontrar la raíz de una función con fsolve

Este artículo explica como calcular la raíz de una función utilizando la función fsolve.

El artículo se basa en un artículo en Inglés "How to find the rooots of a function with fsolve".

La función fsolve retorna la raíces de una ecuación no lineal definida por f(x) = 0.
Para este caso se calculará la raíz de la función f(x) = x^3.

A continuación se muestra el código:


#Import fsolve para calcular la raiz de la funcion x^3

from scipy.optimize import fsolve

#Importar pylab

import pylab

#importar numpy

import numpy



#se calcula la potencia 3 de x con la funcion lambda

potencia3 = lambda x : x**3



#Se calcula la raiz de x^3 iniciando con x = 10

resultado = fsolve(potencia3,10) # starting from x = 10

print resultado



#Se define 400 valores de x entre -4 a 4

x = numpy.linspace(-4,4,400)

#Se genera la grafica, pasando el valor de x

#la potencia 3era de x, el valor de resultado, la potencia 3era de resultado

pylab.plot(x,potencia3(x),resultado,potencia3(resultado),'ro')

#Se define el grid

pylab.grid(b=1)

#Se muestra la grafica

pylab.show()

La gráfica muestra el punto donde se encuentra la raíz de la función:




 .

Graficar una función de 2 variables con matplotlib

Este artículo se basa en el artículo en Ingles "How to plot a function of two variables with matplotlib" .

Se tendrá 2 gráficas de una función de 2 variables, la primera será la gráfica de intensidad y la segunda gráfica será una gráfica 3D.

A continuación se muestra el código:

#!/usr/bin/env python



#De numpy se explorta arange y exp

from numpy import exp,arange

#De pylab se importa meshgrid, cm, imshow, contour, clabel, clorbar, axis, title y show

from pylab import meshgrid,cm,imshow,contour,clabel,colorbar,axis,title,show





from mpl_toolkits.mplot3d import Axes3D

from matplotlib import cm

from matplotlib.ticker import LinearLocator, FormatStrFormatter

import matplotlib.pyplot as plt



#Se define la funcion que se va a graficar

def z_func(x,y):

    return (1-(x**2+y**3))*exp(-(x**2+y**2)/2)



def graficaIntencidad(Z):

    #Se dibuja la funcion

    im = imshow(Z,cmap=cm.RdBu)

    

    #Se agrega el contorno de lineas con sus etiquetas

    cset = contour(Z,arange(-1,1.5,0.2),linewidths=2,cmap=cm.Set2)

    clabel(cset,inline=True,fmt='%1.1f',fontsize=10)

    

    #Se agrega la barra de colores a la derecha

    colorbar(im)

    

    #Se crea el titulo de la grafica con estilo latex

    title('$z=(1-x^2+y^3) e^{-(x^2+y^3)/2}$')

    #Se muestra la grafica

    show()



def grafica3D(X,Y,Z):

    fig = plt.figure()

    ax = fig.gca(projection='3d')

    surf = ax.plot_surface(X, Y, Z, rstride=1, cstride=1,

                           cmap=cm.RdBu,linewidth=0, antialiased=False)

    

    ax.zaxis.set_major_locator(LinearLocator(10))

    ax.zaxis.set_major_formatter(FormatStrFormatter('%.02f'))

    fig.colorbar(surf, shrink=0.5, aspect=5)

    plt.show()



if __name__ == '__main__':

    #rango de valores para x y y.

    x = arange(-3.0,3.0,0.1)

    y = arange(-3.0,3.0,0.1)

    

    #Se define la grilla de puntos

    X,Y = meshgrid(x, y)

    #Se evalua la funcion segun los valores de X y Y

    Z = z_func(X, Y)

    

    graficaIntencidad(Z)

    grafica3D(X,Y,Z)

Al ejecutar el script se mostrará la primera gráfica, al cerrarla aparecerá la segunda gráfica.

La gráfica de intensidad se muestra a continuación:

La gráfica 3D se muestra a continuación: