<SYSTEM_TASK:>
Given the following text description, write Python code to implement the functionality described below step by step
<END_TASK>
<USER_TASK:>
Description:
 Introducción a Jupyter Notebook, Pandas, Matplotlib, etc.
En esta hoja introduciremos la forma de trabajar con Jupyter Notebook, instalado a través de la imagen docker jupyter/scipy-notebook. Veremos cómo los distintos elementos de las librerías de Python interactúan con el notebook para mostrar imágenes, gráficos, etc. También, en las siguientes sesiones los usaremos para acceder a conexiones SQL y a bases de datos NoSQL.
Enlaces a otros tutoriales introductorios (que también se centran en tratamiento de datos para Big Data)
Step1:  A continuación mostramos los paquetes que usaremos regularmente para tratar datos, pandas, numpy, matplotlib. Al ser un programa en Python, se pueden importar paquetes que seguirán siendo válidos hasta el final del notebook.
Step2:  Lo siguiente hace que los gráficos se muestren inline. Para figuras pequeñas se puede utilizar unas figuras interactivas que permiten zoom, usando %maplotlib nbagg.
Step3:  Numpy
Numpy es una de las librerías más utilizadas en Python, y ofrece un interfaz sencillo para operaciones eficientes con números, arrays y matrices. Numpy se utilizará de apoyo muchas veces que haya que hacer procesamiento local de datos recogidos de una base de datos, o como preparación para la graficación de datos. En la celda siguiente se muestra un vídeo introductorio, y también se puede acceder a tutoriales online
Step4:  Numpy permite generar y procesar arrays de datos de forma muy eficiente. A continuación se muestran algunos ejemplos
Step5:  También arrays multidimensionales
Step6:  Se pueden aplicar funciones sobre todo el array o matriz, y el resultado será una matriz idéntica con el operador aplicado. Similar a lo que ocurre con la operación map de algunos lenguajes de programación (incluído Python)
Step7:  También se pueden filtrar los elementos de un array o matriz que cumplan una condición. Para eso se utiliza el operador de indización ([]) con una expresión booleana.
Step8:  ¿Por qué usar Numpy? 
%%capture captura la salida de la ejecución de la celda en la variable dada como parámetro. Después se puede imprimir.
%timeit se utiliza para ejecutar varias veces una instrucción y calcular un promedio de su duración.
Step9:  numpy tiene infinidad de funciones, por lo que sería interesante darse una vuelta por su documentación
Step10:  Pandas
Tutoriales
Step11:  Se puede hacer plot también de una columna contra otra.
Step12:  Valores incompletos. Si no se establecen, se pone a NaN (not a number).
Step13:  fillna() permite cambiar el valor de los datos faltantes.
Step14:  A continuación se muestra un ejemplo de uso de Pandas para leer datos y procesarlos en un Dataframe.
El primer ejemplo completo carga desde el fichero swift-question-dates.txt.gz las fechas de las preguntas en Stackoverflow que contienen el tag "swift".
La función read_csv es capaz de leer cualquier fichero CSV y lo convierte en un "Dataframe", una estructura de tabla que guarda también los nombres y los tipos de las columnas, así como un índice por el que se identificarán las tablas. La lista incluye la fecha en donde se produjo una pregunta con el tag "swift". Como los datos en sí son las fechas, hacemos que la columna de fechas haga a su vez de índice.
Step15:  De la fecha, extraer sólo la fecha (no la hora, que no nos interesa).
Step16:  Añadimos una columna de todo "1" para especificar que cada pregunta cuenta como 1.
Step17:  A los Dataframe de Pandas también se les puede aplicar operaciones de agregación, como groupby o sum. Finalmente, la funcion plot() permite mostrar los datos en un gráfico.
Step18:  A continuación comprobamos con la página de la Wikipedia cuándo apareció el lenguaje Swift
Step19:  A continuación se muestra cómo ubicar posiciones en un mapa con el paquete folium. Se muestra también cómo acceder a distintas posiciones del Dataframe con iloc, loc, etc.
Step20:  El paquete folium permite generar mapas de posiciones. El siguiente ejemplo centra un mapa en Mula y pone un marcador con su nombre
<ASSISTANT_TASK:>
Python Code:
!uname -a
%lsmagic
Explanation: Introducción a Jupyter Notebook, Pandas, Matplotlib, etc.
En esta hoja introduciremos la forma de trabajar con Jupyter Notebook, instalado a través de la imagen docker jupyter/scipy-notebook. Veremos cómo los distintos elementos de las librerías de Python interactúan con el notebook para mostrar imágenes, gráficos, etc. También, en las siguientes sesiones los usaremos para acceder a conexiones SQL y a bases de datos NoSQL.
Enlaces a otros tutoriales introductorios (que también se centran en tratamiento de datos para Big Data): 1 y 2, entre otros muchos.
Pequeña introducción a Docker, Docker-Compose y Jupyter Notebook
Para facilitar la instalación de las herramientas y que todos los alumnos tengan el mismo entorno de trabajo, usaremos la herramienta Docker. Docker es un gestor de contenedores. Permite instalar paquetes pre-instalados de las utilidades que vamos a usar en este curso. En las máquinas del laboratorio está instalado el paquete Docker de Jupyter Notebook que usaremos. Para listar los contenedores docker disponibles en una máquina podemos ejecutar docker images:
bash
$ docker images
REPOSITORY                     TAG                 IMAGE ID            CREATED             SIZE
jupyter/scipy-notebook         latest              fd9cad0aeeeb        2 months ago        6.57GB
neo4j                          latest              9481a852963b        2 months ago        173MB
mongo                          latest              57c67caab3d8        2 months ago        359MB
Docker ofrece también docker-compose, una utilidad que permite conectar entre sí varios contenedores para configurar escenarios más complejos. Por ejemplo, en nuestro caso iniciaremos una base de datos y el servidor de Notebooks. docker-compose también descargará automáticamente los contenedores necesarios. En cada directorio de cada sesión de prácticas existirá un fichero docker-compose.yml, que incluye la configuración para ejecutar el Notebook y los otros contenedores necesarios (por ejemplo otras bases de datos).
Para las prácticas vamos a usar la imagen jupyter/scipy-notebook. La información de cómo usar este contenedor se puede obtener aquí.
Instalación de Docker en Windows
Si se quiere utilizar Docker desde Windows, se puede hacer igualmente. Existen unas instrucciones para usar Docker en Windows. Una vez instalado, habría que instalar la imagen que usaremos con la misma orden docker pull jupyter/scipy-notebook.
Descarga del código de prácticas
Existen varias formas de traer el código de prácticas al contenedor. La más sencilla es ejecutar el siguiente código:
bash
$ git clone https://github.com/dsevilla/bdge.git
Esto creará el directorio bdge con todo el código de las prácticas. Dentro de cada subdirectorio (por ejemplo en este caso intro), habrá un fichero docker-compose.yml, que sirve para ejecutar y conectar los contenedores necesarios para cada parte de la práctica. Así pues:
bash
$ git clone https://github.com/dsevilla/bdge.git
$ cd bdge/intro
$ docker-compose up
Creating network "intro_default" with the default driver
Creating intro_notebook_1 ... done
Attaching to intro_notebook_1
notebook_1  | Execute the command
notebook_1  | [I 10:32:05.350 NotebookApp] Writing notebook server cookie secret to ...
notebook_1  | [I 10:32:05.578 NotebookApp] Serving notebooks from local directory: /home/jovyan
notebook_1  | [I 10:32:05.578 NotebookApp] 0 active kernels 
notebook_1  | [I 10:32:05.578 NotebookApp] Use Control-C to stop this server and shut down all kernels (twice to skip confirmation).
notebook_1  |     to login:
notebook_1  |         http://localhost:8888/
Accediendo a la IP http://localhost:8888/ ó http://127.0.0.1:8888/ se accede al Notebook, y el directorio actual (intro) aparece disponible en la lista de directorios.
Se aconseja guardar el Notebook con otro nombre (File->Rename...) para evitar problemas con las actualizaciones posteriores del repositorio con git.
Para parar el contenedor, se puede ejecutar:
bash
$ docker-compose stop
$ docker-compose rm
(Si no se realiza el rm, docker-compose up volverá a lanzar el contenedor anteriormente parado).
Ejecución del Jupyter Notebook de forma aislada
El Notebook también se puede ejecutar independientemente. Para ejecutar una sesión de Jupyter Notebook hay que escribir:
```bash
$ docker run -it --rm -p 8888:8888 jupyter/scipy-notebook
[I 23:39:02.615 NotebookApp] Writing notebook server cookie secret to ...
[W 23:39:02.712 NotebookApp] WARNING: The notebook server is listening ...
[I 23:39:02.877 NotebookApp] Use Control-C to stop this server and shut down all kernels ...
Copy/paste this URL into your browser when you connect for the first time,
to login with a token:
    http://localhost:8888/?token=<TOKEN>
```
Jupyter Notebook
Los Notebooks contienen una mezcla de texto y código, y se pueden ir ejecutando paso a paso. En general utilizaremos el lenguaje Python en su versión 3, así que las hojas son en realidad un programa Python que se puede ejecutar en orden, junto con imágenes y texto explicativo adjunto.
Al pulsar Ctrl+Intro en una celda, se ejecuta el código de la celda y se muestra el la siguiente celda. Al pulsar Shift+Intro se ejecuta la celda actual y pasa automáticamente a la siguiente.
Existen también "magics", que sirven para obtener información de la hoja, o ejecutar comandos especiales. Por ejemplo, órdenes de shell, como en la siguiente celda. Hay varios tutoriales Online. Por ejemplo: Tutorial.
End of explanation
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import matplotlib
Explanation: A continuación mostramos los paquetes que usaremos regularmente para tratar datos, pandas, numpy, matplotlib. Al ser un programa en Python, se pueden importar paquetes que seguirán siendo válidos hasta el final del notebook.
End of explanation
%matplotlib inline
matplotlib.style.use('ggplot')
Explanation: Lo siguiente hace que los gráficos se muestren inline. Para figuras pequeñas se puede utilizar unas figuras interactivas que permiten zoom, usando %maplotlib nbagg.
End of explanation
from IPython.display import YouTubeVideo
YouTubeVideo('o8fmjaW9a0A') # Yes, it can also embed youtube videos.
Explanation: Numpy
Numpy es una de las librerías más utilizadas en Python, y ofrece un interfaz sencillo para operaciones eficientes con números, arrays y matrices. Numpy se utilizará de apoyo muchas veces que haya que hacer procesamiento local de datos recogidos de una base de datos, o como preparación para la graficación de datos. En la celda siguiente se muestra un vídeo introductorio, y también se puede acceder a tutoriales online: Tutorial.
End of explanation
a = np.array([4,5,6])
print(a.shape)
print(a[0])
a[0] = 9
print (a)
np.arange(10)
np.arange(1,20)
Explanation: Numpy permite generar y procesar arrays de datos de forma muy eficiente. A continuación se muestran algunos ejemplos:
End of explanation
a = np.zeros((2,2))
print (a)
a.ndim
a.dtype
b = np.random.random((2,2))
print (b)
a = np.random.random((2,2))
print(a)
Explanation: También arrays multidimensionales:
End of explanation
print (a >= .5)
Explanation: Se pueden aplicar funciones sobre todo el array o matriz, y el resultado será una matriz idéntica con el operador aplicado. Similar a lo que ocurre con la operación map de algunos lenguajes de programación (incluído Python):
End of explanation
print (a[a >= .5])
Explanation: También se pueden filtrar los elementos de un array o matriz que cumplan una condición. Para eso se utiliza el operador de indización ([]) con una expresión booleana.
End of explanation
%%capture timeit_output
%timeit l1 = range(1,1000)
%timeit l2 = np.arange(1,1000)
print(timeit_output)
x = np.array([[1,2],[3,4]])
print (np.sum(x))  # Compute sum of all elements; prints "10"
print (np.sum(x, axis=0))  # Compute sum of each column; prints "[4 6]"
print (np.sum(x, axis=1))  # Compute sum of each row; prints "[3 7]"
x * 2
x ** 2
Explanation: ¿Por qué usar Numpy? 
%%capture captura la salida de la ejecución de la celda en la variable dada como parámetro. Después se puede imprimir.
%timeit se utiliza para ejecutar varias veces una instrucción y calcular un promedio de su duración.
End of explanation
x = np.arange(0, 3 * np.pi, 0.1)
y = np.sin(x)
plt.subplot()
# Plot the points using matplotlib
plt.plot(x, y)
plt.show()
plt.subplot(211)
plt.plot(range(12))
plt.subplot(212, facecolor='y')
plt.plot(range(100))
plt.show()
# Compute the x and y coordinates for points on sine and cosine curves
x = np.arange(0, 3 * np.pi, 0.1)
y_sin = np.sin(x)
y_cos = np.cos(x)
# Plot the points using matplotlib
plt.plot(x, y_sin)
plt.plot(x, y_cos)
plt.xlabel('x axis label')
plt.ylabel('y axis label')
plt.title('Sine and Cosine')
plt.legend(['Sine', 'Cosine'])
plt.show()
Explanation: numpy tiene infinidad de funciones, por lo que sería interesante darse una vuelta por su documentación: https://docs.scipy.org/doc/.
Matplotlib
Matplotlib permite generar gráficos de forma sencilla. Lo veremos aquí primero conectado sólo con Numpy y después conectado con Pandas.
End of explanation
ts = pd.Series(np.random.randn(1000), index=pd.date_range('1/1/2000', periods=1000))
ts
ts.describe()
ts = ts.cumsum()
ts.plot();
df = pd.DataFrame(np.random.randn(1000, 4), index=ts.index, columns=list('ABCD'))
df = df.cumsum()
df.plot();
Explanation: Pandas
Tutoriales: 1, 2, 3.
Pandas permite gestionar conjuntos de datos n-dimensionales de diferentes formas, y también conectarlo con matplotlib para hacer gráficas.
Los conceptos principales de Pandas son los Dataframes y las Series. La diferencia entre ambas es que la serie guarda sólo una serie (una columna o una fila, depende de como se quiera interpretar), mientras que un Dataframe guarda estructuras multidimensaionales agregando series.
Ambas tienen una (o varias) "columna fantasma", que sirve de índice, y que se puede acceder con d.index (tanto si d es una serie o un dataframe). Si no se especifica un índice, se le añade uno virtual numerando las filas desde cero. Además, los índices pueden ser multidimensionales (por ejemplo, tener un índice por mes y dentro uno por dia de la semana).
End of explanation
df3 = pd.DataFrame(np.random.randn(1000, 2), columns=['B', 'C']).cumsum()
df3['A'] = pd.Series(list(range(len(df3))))
df3.plot(x='A', y='B');
Explanation: Se puede hacer plot también de una columna contra otra.
End of explanation
d = {'one' : pd.Series([1., 2., 3.], index=['a', 'b', 'c']),
     'two' : pd.Series([1., 2., 3., 4.], index=['a', 'b', 'c', 'd'])}
df = pd.DataFrame(d)
df
Explanation: Valores incompletos. Si no se establecen, se pone a NaN (not a number).
End of explanation
df.fillna(0)
pd.DataFrame(d, index=['d', 'b', 'a'])
pd.DataFrame(d, index=['d', 'b', 'a'], columns=['two', 'three'])
Explanation: fillna() permite cambiar el valor de los datos faltantes.
End of explanation
df = pd.read_csv('https://github.com/dsevilla/bdge/raw/master/intro/swift-question-dates.txt.gz',
                 header=None,
                 names=['date'],
                 compression='gzip',
                 parse_dates=['date'],
                 index_col='date')
df
Explanation: A continuación se muestra un ejemplo de uso de Pandas para leer datos y procesarlos en un Dataframe.
El primer ejemplo completo carga desde el fichero swift-question-dates.txt.gz las fechas de las preguntas en Stackoverflow que contienen el tag "swift".
La función read_csv es capaz de leer cualquier fichero CSV y lo convierte en un "Dataframe", una estructura de tabla que guarda también los nombres y los tipos de las columnas, así como un índice por el que se identificarán las tablas. La lista incluye la fecha en donde se produjo una pregunta con el tag "swift". Como los datos en sí son las fechas, hacemos que la columna de fechas haga a su vez de índice.
End of explanation
df.index = df.index.date
Explanation: De la fecha, extraer sólo la fecha (no la hora, que no nos interesa).
End of explanation
df['Count'] = 1
df
Explanation: Añadimos una columna de todo "1" para especificar que cada pregunta cuenta como 1.
End of explanation
accum = df.groupby(df.index).sum()
accum
# Los 30 primeros registros que tengan un número de preguntas mayor que 20 por día.
accum = accum[accum.Count > 20][:30]
accum
accum[accum.Count > 30][:30].plot.bar()
Explanation: A los Dataframe de Pandas también se les puede aplicar operaciones de agregación, como groupby o sum. Finalmente, la funcion plot() permite mostrar los datos en un gráfico.
End of explanation
!pip install lxml
dfwiki = pd.read_html('https://en.wikipedia.org/wiki/Swift_(programming_language)',attrs={'class': 'infobox vevent'})
dfwiki[0]
firstdate = dfwiki[0][1][4]
firstdate
from dateutil.parser import parse
dt = parse(firstdate.split(';')[0])
print (dt.date().isoformat())
print (accum.index[0].isoformat())
assert dt.date().isoformat() == accum.index[0].isoformat()
Explanation: A continuación comprobamos con la página de la Wikipedia cuándo apareció el lenguaje Swift:
End of explanation
# cargar municipios y mostrarlos en el mapa
df = pd.read_csv('https://github.com/dsevilla/bdge/raw/master/intro/municipios-2017.csv.gz',header=0,compression='gzip')
df.head()
df.iloc[0]
df.iloc[0].NOMBRE_ACTUAL
df.loc[:,'NOMBRE_ACTUAL']
df.iloc[:,0]
df.PROVINCIA
df[df.PROVINCIA == 'A Coruña']
mula = df[df.NOMBRE_ACTUAL == 'Mula'].iloc[0]
mula
(mula_lat,mula_lon) = (mula.LATITUD_ETRS89, mula.LONGITUD_ETRS89)
(mula_lat,mula_lon)
Explanation: A continuación se muestra cómo ubicar posiciones en un mapa con el paquete folium. Se muestra también cómo acceder a distintas posiciones del Dataframe con iloc, loc, etc.
End of explanation
!pip install folium
import folium
map = folium.Map(location=[mula_lat, mula_lon],zoom_start=10)
folium.Marker(location = [mula_lat, mula_lon], popup="{} ({} habitantes)".format(mula.NOMBRE_ACTUAL,mula.POBLACION_MUNI)).add_to(map)
map
Explanation: El paquete folium permite generar mapas de posiciones. El siguiente ejemplo centra un mapa en Mula y pone un marcador con su nombre:
End of explanation
<END_TASK>