Jupyter Notebook en acción
Gracias a Martín Nadal conocí esta capacidad de Jupyter de conectar con una API y trabajar el tratamiento de datos con Pandas, una forma de consumir y analizar en tiempo real el contenido de la API.
Accidentes en tráfico en Zaragoza
¿Qué vamos a hacer?
- obtener los datos
- transformar el campo coordenadas
- construir un tabla con motivo del accidente, latitud y longitud
Origen de datos
https://www.zaragoza.es/sede/servicio/catalogo/1500#API
Se observa que:
- El delimitador es el ;
- Tiene dos parámetros,
rows
ystart
Empieza el juego
Para ello primero instalamos Pandas y Folium:
pip install pandas folium
Requirement already satisfied: pandas in /home/flow/.local/pipx/venvs/jupyter/lib/python3.11/site-packages (2.0.1)
Requirement already satisfied: folium in /home/flow/.local/pipx/venvs/jupyter/lib/python3.11/site-packages (0.14.0)
Requirement already satisfied: python-dateutil>=2.8.2 in /home/flow/.local/pipx/venvs/jupyter/lib/python3.11/site-packages (from pandas) (2.8.2)
Requirement already satisfied: pytz>=2020.1 in /home/flow/.local/pipx/venvs/jupyter/lib/python3.11/site-packages (from pandas) (2023.3)
Requirement already satisfied: tzdata>=2022.1 in /home/flow/.local/pipx/venvs/jupyter/lib/python3.11/site-packages (from pandas) (2023.3)
Requirement already satisfied: numpy>=1.21.0 in /home/flow/.local/pipx/venvs/jupyter/lib/python3.11/site-packages (from pandas) (1.24.3)
Requirement already satisfied: branca>=0.6.0 in /home/flow/.local/pipx/venvs/jupyter/lib/python3.11/site-packages (from folium) (0.6.0)
Requirement already satisfied: jinja2>=2.9 in /home/flow/.local/pipx/venvs/jupyter/lib/python3.11/site-packages (from folium) (3.1.2)
Requirement already satisfied: requests in /home/flow/.local/pipx/venvs/jupyter/lib/python3.11/site-packages (from folium) (2.31.0)
Requirement already satisfied: MarkupSafe>=2.0 in /home/flow/.local/pipx/venvs/jupyter/lib/python3.11/site-packages (from jinja2>=2.9->folium) (2.1.2)
Requirement already satisfied: six>=1.5 in /home/flow/.local/pipx/venvs/jupyter/lib/python3.11/site-packages (from python-dateutil>=2.8.2->pandas) (1.16.0)
Requirement already satisfied: charset-normalizer<4,>=2 in /home/flow/.local/pipx/venvs/jupyter/lib/python3.11/site-packages (from requests->folium) (3.2.0)
Requirement already satisfied: idna<4,>=2.5 in /home/flow/.local/pipx/venvs/jupyter/lib/python3.11/site-packages (from requests->folium) (3.4)
Requirement already satisfied: urllib3<3,>=1.21.1 in /home/flow/.local/pipx/venvs/jupyter/lib/python3.11/site-packages (from requests->folium) (2.0.4)
Requirement already satisfied: certifi>=2017.4.17 in /home/flow/.local/pipx/venvs/jupyter/lib/python3.11/site-packages (from requests->folium) (2023.7.22)
[1m[[0m[34;49mnotice[0m[1;39;49m][0m[39;49m A new release of pip is available: [0m[31;49m23.1[0m[39;49m -> [0m[32;49m23.2.1[0m
[1m[[0m[34;49mnotice[0m[1;39;49m][0m[39;49m To update, run: [0m[32;49m/home/flow/.local/pipx/venvs/jupyter/bin/python -m pip install --upgrade pip[0m
Note: you may need to restart the kernel to use updated packages.
Luego importamos Pandas y Folium:
import pandas as pd
import folium
Crear variable
Las variables se asignan con el símbolo “=” y se redactará entrecomillado, ya que se trata de una cadena de caracteres.
url = 'https://www.zaragoza.es/sede/servicio/transporte/accidentalidad-trafico/accidente.csv?rows=100'
Para saber cual es el valor de esta variable, en caso de querer conocerlo, tendremos que introducir el termino “miurl” y este tendrá que marcar un resultado igual a la url propuesta.
url
'https://www.zaragoza.es/sede/servicio/transporte/accidentalidad-trafico/accidente.csv?rows=100'
Si colocamos “miurl” dentro de un parentesis precedido por el comando “type”, mostrará que se trata de una cadena de caracteres.
type(url)
str
A lo cual responde que es de tipo str
, de string
o cadena de caracteres, texto.
Empieza la magia de Pandas
Crear dataframe
La abreviatura que se emplea para los dataframe es “dl”. Existe una función “read_csv()” que lee el formato “csv”. Dentro del paréntesis indicaremos el valor de lo que queremos que lea, en este caso la url.
df = pd.read_csv(url,delimiter=';')
df
id | year | type | accidentType | firstAddress | secondAddress | geometry | reason | area | creationDate | daniosMateriales | falloMecanico | estadoPavimento | tipoEstadoPavimento | estadoAtmosfera | tipoEstadoAtmosfera | afectado | vehiculo | |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
0 | https://www.zaragoza.es/sede/servicio/transpor... | 2014 | SALIDA CALZADA | NaN | COSTA, JOAQUIN | PERAL, ISAAC | -0.8818527060979306,41.649027473051156 | PERDIDA del control por FALTA de ATENCIÓN | NaN | 2014-10-09T00:00:00Z | True | False | BUEN ESTADO | NaN | BUEN ESTADO | NaN | NaN | https://www.zaragoza.es/sede/servicio/transpor... |
1 | https://www.zaragoza.es/sede/servicio/transpor... | 2014 | COLISIÓN ALCANCE | NaN | CADENA(MARQUES DE LA) | NaN | -0.8645810716721081,41.661585829868585 | DISTANCIA DE SEGURIDAD, no mantener | 2560.0 | 2014-10-23T00:00:00Z | False | False | BUEN ESTADO | NaN | BUEN ESTADO | NaN | https://www.zaragoza.es/sede/servicio/transpor... | https://www.zaragoza.es/sede/servicio/transpor... |
2 | https://www.zaragoza.es/sede/servicio/transpor... | 2014 | COLISIÓN ALCANCE | NaN | GOMEZ AVELLANEDA, G. | CASTRO, R. (POETA) | -0.887776415002892,41.666992622958105 | PERDIDA del control por FALTA de ATENCIÓN | 2598.0 | 2014-10-23T00:00:00Z | False | False | BUEN ESTADO | NaN | BUEN ESTADO | NaN | https://www.zaragoza.es/sede/servicio/transpor... | https://www.zaragoza.es/sede/servicio/transpor... |
3 | https://www.zaragoza.es/sede/servicio/transpor... | 2014 | COLIS FRONTOLATERAL | NaN | MONZON | GARCIA CONDOY, H. | -0.8825260453930127,41.62957498750602 | CEDA EL PASO, no respetar prioridad de paso | 2555.0 | 2014-10-23T00:00:00Z | False | False | BUEN ESTADO | NaN | BUEN ESTADO | NaN | https://www.zaragoza.es/sede/servicio/transpor... | https://www.zaragoza.es/sede/servicio/transpor... |
4 | https://www.zaragoza.es/sede/servicio/transpor... | 2014 | SALIDA CALZADA | NaN | RIOJA | NAVARRA, AVENIDA DE | -0.908314757720389,41.6562121210704 | PERDIDA del control por VELOCIDAD INADECUADA | 2554.0 | 2014-10-24T00:00:00Z | False | False | BUEN ESTADO | NaN | BUEN ESTADO | NaN | https://www.zaragoza.es/sede/servicio/transpor... | https://www.zaragoza.es/sede/servicio/transpor... |
... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... |
95 | https://www.zaragoza.es/sede/servicio/transpor... | 2014 | OTRAS | NaN | MIRAL, DOMINGO | NaN | -0.8990662796872798,41.63977012001253 | PERDIDA del control por FALTA de ATENCIÓN | NaN | 2014-07-30T00:00:00Z | True | False | BUEN ESTADO | NaN | BUEN ESTADO | NaN | NaN | https://www.zaragoza.es/sede/servicio/transpor... |
96 | https://www.zaragoza.es/sede/servicio/transpor... | 2014 | COLISIÓN ALCANCE | NaN | BUÑUEL,LUIS (PARQUE DEL AGUA) | NaN | -0.9072756956226459,41.670910841846876 | PERDIDA del control por FALTA de ATENCIÓN | 2071.0 | 2014-07-31T00:00:00Z | True | False | BUEN ESTADO | NaN | BUEN ESTADO | NaN | NaN | https://www.zaragoza.es/sede/servicio/transpor... |
97 | https://www.zaragoza.es/sede/servicio/transpor... | 2014 | SALIDA CALZADA | NaN | ALBAR, MANUEL GL. | ILUSTRACION, AV. DE LA | -0.9226018969034585,41.62757051008441 | PERDIDA del control por FALTA de ATENCIÓN | 1969.0 | 2014-07-25T00:00:00Z | False | False | BUEN ESTADO | NaN | BUEN ESTADO | NaN | https://www.zaragoza.es/sede/servicio/transpor... | https://www.zaragoza.es/sede/servicio/transpor... |
98 | https://www.zaragoza.es/sede/servicio/transpor... | 2014 | COLIS FRONTOLATERAL | NaN | ECHEGARAY Y CABALLERO | SAN VICENTE PAUL | -0.8735234620830842,41.65507219335992 | SEMÁFORO, no respetar prioridad de paso | 1970.0 | 2014-07-26T00:00:00Z | False | False | BUEN ESTADO | NaN | BUEN ESTADO | NaN | https://www.zaragoza.es/sede/servicio/transpor... | https://www.zaragoza.es/sede/servicio/transpor... |
99 | https://www.zaragoza.es/sede/servicio/transpor... | 2014 | SALIDA CALZADA | NaN | CESAR AUGUSTO, AVDA | NaN | -0.8869504077778204,41.65022964156985 | PERDIDA del control por FALTA de ATENCIÓN | 1971.0 | 2014-07-09T00:00:00Z | True | False | BUEN ESTADO | NaN | BUEN ESTADO | NaN | NaN | https://www.zaragoza.es/sede/servicio/transpor... |
100 rows × 18 columns
Aquí tenemos todos los datos pero mejor si lo evitamos, son 27000 accidentes y puede ir lento.
df = pd.read_csv('http://muimota.net/ojoaldato/accidentes.csv')
df
id | year | type | accidentType | firstAddress | secondAddress | geometry | reason | area | creationDate | daniosMateriales | falloMecanico | estadoPavimento | tipoEstadoPavimento | estadoAtmosfera | tipoEstadoAtmosfera | afectado | vehiculo | |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
0 | https://www.zaragoza.es/sede/servicio/transpor... | 2014 | SALIDA CALZADA | NaN | COSTA, JOAQUIN | PERAL, ISAAC | -0.8818527060979306,41.649027473051156 | PERDIDA del control por FALTA de ATENCIÓN | NaN | 2014-10-09T00:00:00Z | True | False | BUEN ESTADO | NaN | BUEN ESTADO | NaN | NaN | https://www.zaragoza.es/sede/servicio/transpor... |
1 | https://www.zaragoza.es/sede/servicio/transpor... | 2014 | COLISIÓN ALCANCE | NaN | CADENA(MARQUES DE LA) | NaN | -0.8645810716721081,41.661585829868585 | DISTANCIA DE SEGURIDAD, no mantener | 2560.0 | 2014-10-23T00:00:00Z | False | False | BUEN ESTADO | NaN | BUEN ESTADO | NaN | https://www.zaragoza.es/sede/servicio/transpor... | https://www.zaragoza.es/sede/servicio/transpor... |
2 | https://www.zaragoza.es/sede/servicio/transpor... | 2014 | COLISIÓN ALCANCE | NaN | GOMEZ AVELLANEDA, G. | CASTRO, R. (POETA) | -0.887776415002892,41.666992622958105 | PERDIDA del control por FALTA de ATENCIÓN | 2598.0 | 2014-10-23T00:00:00Z | False | False | BUEN ESTADO | NaN | BUEN ESTADO | NaN | https://www.zaragoza.es/sede/servicio/transpor... | https://www.zaragoza.es/sede/servicio/transpor... |
3 | https://www.zaragoza.es/sede/servicio/transpor... | 2014 | COLIS FRONTOLATERAL | NaN | MONZON | GARCIA CONDOY, H. | -0.8825260453930127,41.62957498750602 | CEDA EL PASO, no respetar prioridad de paso | 2555.0 | 2014-10-23T00:00:00Z | False | False | BUEN ESTADO | NaN | BUEN ESTADO | NaN | https://www.zaragoza.es/sede/servicio/transpor... | https://www.zaragoza.es/sede/servicio/transpor... |
4 | https://www.zaragoza.es/sede/servicio/transpor... | 2014 | SALIDA CALZADA | NaN | RIOJA | NAVARRA, AVENIDA DE | -0.908314757720389,41.6562121210704 | PERDIDA del control por VELOCIDAD INADECUADA | 2554.0 | 2014-10-24T00:00:00Z | False | False | BUEN ESTADO | NaN | BUEN ESTADO | NaN | https://www.zaragoza.es/sede/servicio/transpor... | https://www.zaragoza.es/sede/servicio/transpor... |
... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... |
27495 | https://www.zaragoza.es/sede/servicio/transpor... | 2019 | COLISIÓN LATERAL | NaN | PLEYADES, LAS | BOYERO | -0.9337782877014544,41.63888841722081 | INCORPORARSE sin las debidas precauciones | 2512.0 | 2019-09-20T00:00:00Z | False | False | BUEN ESTADO | NaN | BUEN ESTADO | NaN | https://www.zaragoza.es/sede/servicio/transpor... | https://www.zaragoza.es/sede/servicio/transpor... |
27496 | https://www.zaragoza.es/sede/servicio/transpor... | 2019 | COLISIÓN LATERAL | NaN | UNIVERSITAS, VIA | NaN | -0.9067375759951974,41.644789184898926 | INCORPORARSE sin las debidas precauciones | 2513.0 | 2019-09-18T00:00:00Z | True | False | BUEN ESTADO | NaN | BUEN ESTADO | NaN | NaN | https://www.zaragoza.es/sede/servicio/transpor... |
27497 | https://www.zaragoza.es/sede/servicio/transpor... | 2019 | COLISIÓN LATERAL | NaN | CANOVAS, ANTONIO | NaN | -0.8907497377774148,41.64811436227578 | INVADIR otro carril en el mismo sentido de cir... | 2707.0 | 2019-09-21T00:00:00Z | True | False | BUEN ESTADO | NaN | BUEN ESTADO | NaN | NaN | https://www.zaragoza.es/sede/servicio/transpor... |
27498 | https://www.zaragoza.es/sede/servicio/transpor... | 2019 | SALIDA CALZADA | NaN | LEGAZ LACAMBRA, LUIS | GOMEZ AVELLANEDA, G. | -0.8908180267513072,41.676074625860785 | PERDIDA del control por FALTA de ATENCIÓN | 2572.0 | 2019-09-22T00:00:00Z | True | False | BUEN ESTADO | NaN | BUEN ESTADO | NaN | NaN | https://www.zaragoza.es/sede/servicio/transpor... |
27499 | https://www.zaragoza.es/sede/servicio/transpor... | 2019 | COLISIÓN LATERAL | NaN | RODRIGUEZ AYUSO, MANUEL | BIEL | -0.9245669583272559,41.645615385662296 | INVADIR otro carril en el mismo sentido de cir... | 2540.0 | 2019-09-20T00:00:00Z | False | False | BUEN ESTADO | NaN | BUEN ESTADO | NaN | https://www.zaragoza.es/sede/servicio/transpor... | https://www.zaragoza.es/sede/servicio/transpor... |
27500 rows × 18 columns
Viendo estos datos a Martín le interesó explorar la columna reason
y saber qué valores únicos había:
df['reason'].unique()
array(['PERDIDA del control por FALTA de ATENCIÓN',
'DISTANCIA DE SEGURIDAD, no mantener',
'CEDA EL PASO, no respetar prioridad de paso',
'PERDIDA del control por VELOCIDAD INADECUADA',
'Caída de ocupante en Transporte Público',
'PEATÓN cruza calz SIN PREFER. fuera de paso',
'INVADIR otro carril en el mismo sentido de circulación',
'PEATÓN cruza calz SIN PREFER. en PASO CON semáforo',
'PUERTA abierta incorrectamente', 'MARCHA ATRÁS',
'SEMÁFORO, no respetar prioridad de paso', 'OTRAS CAUSAS',
'PEATÓN cruza calz CON PREFER. en PASO CON semáforo',
'PEATÓN cruza calz CON PREFER. en PASO SIN semáforo',
'PEATÓN cruza calz CON PREFER. en PASO SIN semáforo',
'INCORPORARSE sin las debidas precauciones',
'GIROS: no respetar señal ó no ceñirse a la dirección',
'PEATÓN cruza calz CON PREFER. en PASO CON semáforo',
'Infracción Penal (con denuncia)',
'PEATÓN atropellado sobre la acera ó refugio',
'PEATÓN cruza calz SIN PREFER. en PASO CON semáforo',
'STOP, no respetar prioridad de paso',
'SIN PODER DETERMINAR, faltan datos',
'INVADIR otro carril en sentido contrario a la circulación',
'PREFERENCIA EN GLORIETA, no respetar',
'PEATÓN cruza calz CON PREFER. fuera de PASO (esquina)',
'DIRECCIÓN CONTRARIA, circular en',
'SIN PODER DETERMINAR, faltan datos',
'ESTACIONADO INCORRECTAMENTE',
'PREFERENCIA A LA DERECHA, no respetar',
'PREFERENCIA A LA DERECHA, no respetar',
'ADELANTAMIENTO incorrecto', 'Daños propiedad', 'Otras causas',
'INCORPORARSE un BUS URBANO a la circulac. desde parada señaliz.',
'CAIDA DE PEATÓN EN AUTOBUS', 'Daños (Propiedad)', nan,
'INCORPORARSE sin las debidas precauciones)',
'PEATÓN cruza calz fuera de PASO (esquina)',
'Infracción Penal (sin denuncia)'], dtype=object)
Ademá, se propuso ver si podía utilizar el valor de la columna geometry
:
df['geometry']
0 -0.8818527060979306,41.649027473051156
1 -0.8645810716721081,41.661585829868585
2 -0.887776415002892,41.666992622958105
3 -0.8825260453930127,41.62957498750602
4 -0.908314757720389,41.6562121210704
...
27495 -0.9337782877014544,41.63888841722081
27496 -0.9067375759951974,41.644789184898926
27497 -0.8907497377774148,41.64811436227578
27498 -0.8908180267513072,41.676074625860785
27499 -0.9245669583272559,41.645615385662296
Name: geometry, Length: 27500, dtype: object
Resulta que era un objeto de tipo cadena, que contenía las dos coordenadas y, además, que estaban invertidas en el orden. Había que convertirlo. Primero las longitudes y luego las latitudes:
longitudes = []
for coordenadasStr in df['geometry']:
pointStr = coordenadasStr.split(',')
longitudes += [float(pointStr[0])]
latitudes = []
for coordenadasStr in df['geometry']:
pointStr = coordenadasStr.split(',')
latitudes += [float(pointStr[1])]
Con esto crea un dataframe
concreto:
coordenadas = pd.DataFrame({'long':longitudes,'lat':latitudes})
coordenadas
long | lat | |
---|---|---|
0 | -0.881853 | 41.649027 |
1 | -0.864581 | 41.661586 |
2 | -0.887776 | 41.666993 |
3 | -0.882526 | 41.629575 |
4 | -0.908315 | 41.656212 |
... | ... | ... |
27495 | -0.933778 | 41.638888 |
27496 | -0.906738 | 41.644789 |
27497 | -0.890750 | 41.648114 |
27498 | -0.890818 | 41.676075 |
27499 | -0.924567 | 41.645615 |
27500 rows × 2 columns
Y se crea otro dataframe
de la unión de la columna type
y del dataframe coordenadas
:
accidentes = pd.concat([df['type'],coordenadas],axis=1)
accidentes
type | long | lat | |
---|---|---|---|
0 | SALIDA CALZADA | -0.881853 | 41.649027 |
1 | COLISIÓN ALCANCE | -0.864581 | 41.661586 |
2 | COLISIÓN ALCANCE | -0.887776 | 41.666993 |
3 | COLIS FRONTOLATERAL | -0.882526 | 41.629575 |
4 | SALIDA CALZADA | -0.908315 | 41.656212 |
... | ... | ... | ... |
27495 | COLISIÓN LATERAL | -0.933778 | 41.638888 |
27496 | COLISIÓN LATERAL | -0.906738 | 41.644789 |
27497 | COLISIÓN LATERAL | -0.890750 | 41.648114 |
27498 | SALIDA CALZADA | -0.890818 | 41.676075 |
27499 | COLISIÓN LATERAL | -0.924567 | 41.645615 |
27500 rows × 3 columns
Crea el mapa con Folium
mapa = folium.Map(location=[41.64,-0.88])
mapa