La base de datos de movimientos aeroportuarios en Argentina contiene información con despegues y aterrizajes en los aeropuertos nacionales.
A partir de esto, pensé en aplicar herramientas de ETL en Pandas para armar algunas visualizaiones usando Geopandas, Seaborn y Plotl.
En archivo .html fue exportado de Jupyter Notebook y editado, agregado las visualizaciones en formato png. En el repositorio, se pueden descargar los archivos y los datasets.
import pandas as pd
import numpy as np
import geopandas as gpd
import seaborn as sns
import matplotlib.pyplot as plt
import plotly.graph_objects as go
import plotly.express as px
location = pd.read_csv("GlobalAirportDatabase.txt", sep=":")
location.reset_index(inplace=True)
location.drop(["3","5","6","7","8","9","10","11","12","13"], axis = 1,inplace = True)
location.columns = ["ICAO","IATA","Aeropuerto","Pais","Lat","Long"]
location.dropna(inplace=True)
location.head()
ICAO | IATA | Aeropuerto | Pais | Lat | Long | |
---|---|---|---|---|---|---|
0 | AYGA | GKA | GOROKA | PAPUA NEW GUINEA | -6.082 | 145.392 |
2 | AYMD | MAG | MADANG | PAPUA NEW GUINEA | -5.207 | 145.789 |
3 | AYMH | HGU | MOUNT HAGEN | PAPUA NEW GUINEA | -5.826 | 144.296 |
4 | AYNZ | LAE | NADZAB | PAPUA NEW GUINEA | -6.570 | 146.726 |
5 | AYPY | POM | PORT MORESBY JACKSONS INTERNATIONAL | PAPUA NEW GUINEA | -9.443 | 147.220 |
Información de datos.gob.ar. Concateno los datasets y genero uno nuevo
datos2014 = pd.read_csv("aterrizajes-y-despegues-registrados-por-eana-2014 .csv",sep=";")
datos2015 = pd.read_csv("aterrizajes-y-despegues-registrados-por-eana-2015.csv",sep=";")
datos2016 = pd.read_csv("aterrizajes-y-despegues-registrados-por-eana-2016.csv",sep=";")
datos2017 = pd.read_csv("aterrizajes-y-despegues-registrados-por-eana-2017.csv",sep=";")
datos2018 = pd.read_csv("aterrizajes-y-despegues-registrados-por-eana-2018.csv",sep=";")
datos2019 = pd.read_csv("aterrizajes-y-despegues-registrados-por-eana-2019.csv",sep=";")
datos2020 = pd.read_csv("aterrizajes-y-despegues-registrados-por-eana-2020.csv",sep=";")
datos = pd.concat([datos2014,datos2015,datos2016,datos2017,datos2018,datos2019,datos2020],axis = 0)
datos.head()
Fecha | Hora | Clase de Vuelo | Clasificaci�n Vuelo | Tipo de Movimiento | Origen OACI | Destino OACI | Aerolinea Nombre | Aeronave | |
---|---|---|---|---|---|---|---|---|---|
0 | 01/01/2014 | 1.0 | No Regular | Cabotaje | Aterrizaje | SAME | SACO | SOL L�neas A�reas | SAAB SF34 |
1 | 01/01/2014 | 1.0 | Regular | Internacional | Despegue | SABE | SBGR | Gol Transportes A�reo | BOEING B-737 |
2 | 01/01/2014 | 1.0 | Regular | Cabotaje | Aterrizaje | SASJ | SABE | Austral L�neas A�reas | EMBRAER E-190 |
3 | 01/01/2014 | 1.0 | Regular | Cabotaje | Aterrizaje | SABE | SACO | Austral L�neas A�reas | EMBRAER E-190 |
4 | 01/01/2014 | 1.0 | Regular | Internacional | Despegue | SAEZ | KIAH | United Airlines | BOEING B-767 |
En cada registro de datos, agrego información geográfica de ambos aeropuertos (despegue y aterrizaje). Para eso duplico la tabla location, generando una para despegues y otra para aterrizajes
origen = location
origen.columns=["Origen OACI", "Origen IATA", "Airport Origen", "Country Origen", "Lat Origen", "Long Origen"]
origen.head()
Origen OACI | Origen IATA | Airport Origen | Country Origen | Lat Origen | Long Origen | |
---|---|---|---|---|---|---|
0 | AYGA | GKA | GOROKA | PAPUA NEW GUINEA | -6.082 | 145.392 |
2 | AYMD | MAG | MADANG | PAPUA NEW GUINEA | -5.207 | 145.789 |
3 | AYMH | HGU | MOUNT HAGEN | PAPUA NEW GUINEA | -5.826 | 144.296 |
4 | AYNZ | LAE | NADZAB | PAPUA NEW GUINEA | -6.570 | 146.726 |
5 | AYPY | POM | PORT MORESBY JACKSONS INTERNATIONAL | PAPUA NEW GUINEA | -9.443 | 147.220 |
union = pd.merge(datos, origen,left_on="Origen OACI", right_on = "Origen OACI", how = "outer")
destino = location
destino.columns = ["Destino OACI", "Destino IATA", "Airport Destino", "Country Destino", "Lat Destino", "Long Destino"]
union2 = pd.merge(union, destino,left_on="Destino OACI", right_on = "Destino OACI")
union2.head()
Fecha | Hora | Clase de Vuelo | Clasificaci�n Vuelo | Tipo de Movimiento | Origen OACI | Destino OACI | Aerolinea Nombre | Aeronave | Origen IATA | Airport Origen | Country Origen | Lat Origen | Long Origen | Destino IATA | Airport Destino | Country Destino | Lat Destino | Long Destino | |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
0 | 10/01/2019 | 7.0 | Regular | Cabotaje | Aterrizaje | SAME | SABE | LATAM Argentina | AIRBUS A-320 | MDZ | EL PLUMERILLO | ARGENTINA | -32.832 | -68.793 | AEP | AEROPARQUE JORGE NEWBERY | ARGENTINA | -34.559 | -58.416 |
1 | 10/01/2019 | 7.0 | Regular | Cabotaje | Despegue | SAME | SABE | Norwegian Air Argenti | BOEING B-737 | MDZ | EL PLUMERILLO | ARGENTINA | -32.832 | -68.793 | AEP | AEROPARQUE JORGE NEWBERY | ARGENTINA | -34.559 | -58.416 |
2 | 10/01/2019 | 15.0 | Regular | Cabotaje | Aterrizaje | SAME | SABE | Norwegian Air Argenti | BOEING B-737 | MDZ | EL PLUMERILLO | ARGENTINA | -32.832 | -68.793 | AEP | AEROPARQUE JORGE NEWBERY | ARGENTINA | -34.559 | -58.416 |
3 | 10/01/2019 | 9.0 | Regular | Cabotaje | Despegue | SAME | SABE | Aerol�neas Argentinas | BOEING B-737 | MDZ | EL PLUMERILLO | ARGENTINA | -32.832 | -68.793 | AEP | AEROPARQUE JORGE NEWBERY | ARGENTINA | -34.559 | -58.416 |
4 | 10/01/2019 | 19.0 | Regular | Cabotaje | Despegue | SAME | SABE | Norwegian Air Argenti | BOEING B-737 | MDZ | EL PLUMERILLO | ARGENTINA | -32.832 | -68.793 | AEP | AEROPARQUE JORGE NEWBERY | ARGENTINA | -34.559 | -58.416 |
union2.drop(["Hora", "Clase de Vuelo", "Clasificaci�n Vuelo", "Origen OACI", "Destino OACI"], axis = 1, inplace = True)
datosOK = union2[union2["Tipo de Movimiento"]=="Aterrizaje"]
print("Dataset Size: ", datosOK.shape)
Dataset Size: (178107, 14)
datosOK.head()
Fecha | Tipo de Movimiento | Aerolinea Nombre | Aeronave | Origen IATA | Airport Origen | Country Origen | Lat Origen | Long Origen | Destino IATA | Airport Destino | Country Destino | Lat Destino | Long Destino | |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
0 | 10/01/2019 | Aterrizaje | LATAM Argentina | AIRBUS A-320 | MDZ | EL PLUMERILLO | ARGENTINA | -32.832 | -68.793 | AEP | AEROPARQUE JORGE NEWBERY | ARGENTINA | -34.559 | -58.416 |
2 | 10/01/2019 | Aterrizaje | Norwegian Air Argenti | BOEING B-737 | MDZ | EL PLUMERILLO | ARGENTINA | -32.832 | -68.793 | AEP | AEROPARQUE JORGE NEWBERY | ARGENTINA | -34.559 | -58.416 |
6 | 10/01/2019 | Aterrizaje | Norwegian Air Argenti | BOEING B-737 | MDZ | EL PLUMERILLO | ARGENTINA | -32.832 | -68.793 | AEP | AEROPARQUE JORGE NEWBERY | ARGENTINA | -34.559 | -58.416 |
9 | 10/01/2019 | Aterrizaje | Norwegian Air Argenti | BOEING B-737 | MDZ | EL PLUMERILLO | ARGENTINA | -32.832 | -68.793 | AEP | AEROPARQUE JORGE NEWBERY | ARGENTINA | -34.559 | -58.416 |
11 | 10/01/2019 | Aterrizaje | Aerol�neas Argentinas | BOEING B-737 | MDZ | EL PLUMERILLO | ARGENTINA | -32.832 | -68.793 | AEP | AEROPARQUE JORGE NEWBERY | ARGENTINA | -34.559 | -58.416 |
Primero, usaremos la librería geopandas para graficar las rutas aéreas en el DataSet. Separaremos esto en dos gráficos, vuelos locales y nacionales.
locales = datosOK[datosOK["Country Origen"]=="ARGENTINA"]
localesGroup = locales.groupby(["Lat Origen","Long Origen","Lat Destino","Long Destino"]).count()[["Fecha"]].reset_index()
localesGroup.columns = ["Lat Origen","Long Origen","Lat Destino","Long Destino","Vuelos"]
internacionales = datosOK[datosOK["Country Origen"]!="ARGENTINA"]
internacionalesGroup=internacionales.groupby(["Lat Origen","Long Origen","Lat Destino","Long Destino"]).count()[["Fecha"]].reset_index()
internacionalesGroup.columns = ["Lat Origen","Long Origen","Lat Destino","Long Destino","Vuelos"]
fig = go.Figure()
origen_a_dest = zip(internacionalesGroup["Lat Origen"], internacionalesGroup["Long Origen"],
internacionalesGroup["Lat Destino"], internacionalesGroup["Long Destino"],
internacionalesGroup["Vuelos"])
##
for olat,olon, dlat, dlon, vuelos in origen_a_dest:
fig.add_trace(go.Scattergeo(
lat = [olat,dlat],
lon = [olon, dlon],
mode = 'lines',
line = dict(width = 0.05*np.log(vuelos), color="red")
))
##
fig.update_layout(
height=600, width=800, margin={"t":50,"b":0,"l":0, "r":0, "pad":0},
showlegend=False,
title={
'text': "Vuelos con origen en aeropuertos argentinos y destinos internacionales",
'y':0.97,
'x':0.5,
'xanchor': 'center',
'yanchor': 'top'},
geo = dict(projection_type = 'orthographic', showland = True),
)
fig.show()
fig = go.Figure()
origen_a_dest = zip(localesGroup["Lat Origen"], localesGroup["Long Origen"],
localesGroup["Lat Destino"], localesGroup["Long Destino"],
localesGroup["Vuelos"])
##
for olat,olon, dlat, dlon, vuelos in origen_a_dest:
fig.add_trace(go.Scattergeo(
lat = [olat,dlat],
lon = [olon, dlon],
mode = 'lines',
line = dict(width = 0.05*np.log(vuelos), color="red")
))
##
fig.update_layout(
height=600, width=800, margin={"t":0,"b":0,"l":0, "r":0, "pad":0},
showlegend=False,
title={
'text': "Vuelos con origen en aeropuertos argentinos y destinos nacionales",
'y':0.97,
'x':0.5,
'xanchor': 'center',
'yanchor': 'top'},
geo = dict(projection_type = 'mercator',scope = 'south america'),
)
fig.show()
Dado que la mayoría de las rutas locales son entre Aeroparque y otros aeropuertos, podemos visualizar en un gráfico tipo treemap esta división
destinosAEP=locales[locales["Origen IATA"]=="AEP"].groupby("Destino IATA").count()[['Fecha']]
destinosAEP["ORIGEN"] = "AEP"
destinosAEP.reset_index(inplace=True)
destinosAEP.columns= ["Destino", "Cantidad", "Origen"]
fig = px.treemap(destinosAEP, path=['Origen', 'Destino'], values='Cantidad',
color_continuous_midpoint=np.average(destinosAEP['Cantidad'], weights=destinosAEP['Cantidad']))
fig.update_layout(
height=600, width=800, margin={"t":40,"b":0,"l":0, "r":0, "pad":0},
title={
'text': "Destinos nacionales con origen en Aeroparque",
'y':0.97,
'x':0.5,
'xanchor': 'center',
'yanchor': 'top'},
)
fig.show()
Por último, podemos ver qué aeronave se utiliza más en todos los vuelos desde argentina
aeronaves=datosOK.groupby("Aeronave").count()[["Fecha"]]
aeronaves.reset_index(inplace=True)
aeronaves.columns = ["Aeronave", "Cantidad de Vuelos"]
aeronaves.head()
Aeronave | Cantidad de Vuelos | |
---|---|---|
0 | AERO AC50 | 13 |
1 | AERO AC68 | 3 |
2 | AERO BOERO AB11 | 89 |
3 | AERO BOERO AB18 | 34 |
4 | AERO COMMANDER | 17 |
Graficaremos únicamente aquellas aviones que aparecen más de 500 veces, dado que hay muchos aviones muy pequeños con muy pocos viajes en todos los años estudiados
plt.figure(figsize=(15, 15))
sns.barplot(y="Aeronave",x="Cantidad de Vuelos",
data = aeronaves[aeronaves["Cantidad de Vuelos"]>500],palette="Blues_d")
<AxesSubplot:xlabel='Cantidad de Vuelos', ylabel='Aeronave'>