From 3e8ee880b1ebf77afbd528d856f4f14819dbaad7 Mon Sep 17 00:00:00 2001 From: Felipe Gonzalez Date: Tue, 19 Nov 2024 15:19:17 -0300 Subject: [PATCH] Dev test03 (#183) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Lineas de deseo and dash - modificación en líneas de deseo para que guarde cada procesamiento de polígono/zona para minimizar un poco el uso de memoria - Arreglos en el dash: se agregó filtro por zona en lineas de deseo y polígonos, indicadores de trasbordos en zonas. --------- Co-authored-by: Sebastian Anapolsky --- .../configuraciones_generales_2019_m1.yaml | 22 +- urbantrips/dashboard/dash_utils.py | 35 +- .../pages/3_L\303\255neas de Deseo.py" | 172 +++-- urbantrips/dashboard/pages/4_Poligonos.py | 43 +- .../pages/5_An\303\241lisis de zonas.py" | 340 ++++----- urbantrips/lineas_deseo/lineas_deseo.py | 646 ++++++++++-------- 6 files changed, 723 insertions(+), 535 deletions(-) diff --git a/configs/configuraciones_generales_2019_m1.yaml b/configs/configuraciones_generales_2019_m1.yaml index c87cf83..73162a1 100644 --- a/configs/configuraciones_generales_2019_m1.yaml +++ b/configs/configuraciones_generales_2019_m1.yaml @@ -94,19 +94,9 @@ filtro_latlong_bbox: # Zonificaciones zonificaciones: - geo1: "coronas.geojson" - var1: "Corona" + geo1: "partidos.geojson" + var1: "Partido" orden1: [ - "CABA", - "Primer cordón", - "Segundo cordón", - "Tercer cordón", - "RMBA", - ] - - geo2: "partidos.geojson" - var2: "Partido" - orden2: [ "Comuna 1", "Comuna 2", "Comuna 3", @@ -172,9 +162,9 @@ zonificaciones: "Zárate", ] - geo3: "partidos.geojson" - var3: "Zona" - orden3: [ + geo2: "partidos.geojson" + var2: "Zona" + orden2: [ "CABA", "Sur", "Oeste", @@ -190,7 +180,7 @@ zonificaciones: var5: orden5: -poligonos: # Especificar una capa geográfica de polígonos en formato .geojson. El archivo requiere las siguientes columnas: ['id', 'tipo', 'geometry']. 'id' es el id o nombre del polígono, tipo puede ser 'poligono' o 'cuenca'. +poligonos: "poligonos.geojson" # Especificar una capa geográfica de polígonos en formato .geojson. El archivo requiere las siguientes columnas: ['id', 'tipo', 'geometry']. 'id' es el id o nombre del polígono, tipo puede ser 'poligono' o 'cuenca'. tiempos_viaje_estaciones: # Especificar una tabla de tiempo de viaje en minutos entre estaciones para modos sin gps diff --git a/urbantrips/dashboard/dash_utils.py b/urbantrips/dashboard/dash_utils.py index 300e23f..7c9b7c5 100644 --- a/urbantrips/dashboard/dash_utils.py +++ b/urbantrips/dashboard/dash_utils.py @@ -30,7 +30,7 @@ def leer_configs_generales(): return config -def leer_alias(tipo='data'): +def leer_alias(tipo='dash'): """ Esta funcion toma un tipo de datos (data o insumos) y devuelve el alias seteado en el archivo de congifuracion @@ -53,7 +53,7 @@ def leer_alias(tipo='data'): return alias -def traigo_db_path(tipo='data'): +def traigo_db_path(tipo='dash'): """ Esta funcion toma un tipo de datos (data o insumos) y devuelve el path a una base de datos con esa informacion @@ -62,12 +62,13 @@ def traigo_db_path(tipo='data'): raise ValueError('tipo invalido: %s' % tipo) alias = leer_alias(tipo) + db_path = os.path.join("data", "db", f"{alias}{tipo}.sqlite") return db_path -def iniciar_conexion_db(tipo='data'): +def iniciar_conexion_db(tipo='dash'): """" Esta funcion toma un tipo de datos (data o insumos) y devuelve una conexion sqlite a la db @@ -76,6 +77,7 @@ def iniciar_conexion_db(tipo='data'): assert os.path.isfile( db_path), f'No existe la base de datos para el dashboard en {db_path}' conn = sqlite3.connect(db_path, timeout=10) + return conn # Calculate weighted mean, handling division by zero or empty inputs @@ -597,4 +599,29 @@ def bring_latlon(): latlon = [lat, lon] except: latlon = [-34.593, -58.451] - return latlon \ No newline at end of file + return latlon + +@st.cache_data +def traigo_zonas_values(tipo = 'etapas'): + + if tipo == 'etapas': + table = 'agg_etapas' + else: + table = 'poly_etapas' + + + query = f""" + SELECT DISTINCT zona, inicio_norm FROM {table} + UNION + SELECT DISTINCT zona, transfer1_norm FROM {table} + UNION + SELECT DISTINCT zona, transfer2_norm FROM {table} + UNION + SELECT DISTINCT zona, fin_norm FROM {table}; + """ + zonas_values = etapas=levanto_tabla_sql(table, 'dash', query) + zonas_values = zonas_values[(zonas_values.inicio_norm!='')& + (zonas_values.inicio_norm.notna())& + (zonas_values.inicio_norm!=' (cuenca)')].sort_values(['zona', 'inicio_norm']).rename(columns={'inicio_norm':'Nombre'}) + + return zonas_values \ No newline at end of file diff --git "a/urbantrips/dashboard/pages/3_L\303\255neas de Deseo.py" "b/urbantrips/dashboard/pages/3_L\303\255neas de Deseo.py" index bf57c32..8d1bc33 100644 --- "a/urbantrips/dashboard/pages/3_L\303\255neas de Deseo.py" +++ "b/urbantrips/dashboard/pages/3_L\303\255neas de Deseo.py" @@ -1,5 +1,6 @@ import streamlit as st import pandas as pd +import numpy as np import geopandas as gpd import folium from streamlit_folium import st_folium, folium_static @@ -12,7 +13,7 @@ create_data_folium, traigo_indicadores, extract_hex_colors_from_cmap, iniciar_conexion_db, normalize_vars, - bring_latlon + bring_latlon, traigo_zonas_values ) def crear_mapa_lineas_deseo(df_viajes, @@ -265,27 +266,51 @@ def levanto_tabla_sql_local(tabla_sql, tabla_tipo="dash", query=''): return tabla def traigo_socio_indicadores(socio_indicadores): - - df = socio_indicadores[socio_indicadores.tabla=='viajes-genero-tarifa'].copy() - totals = pd.crosstab(values=df.factor_expansion_linea, columns=df.Genero, index=df.Tarifa, aggfunc='sum', margins=True, margins_name='Total', normalize=False).fillna(0).round().astype(int).apply(lambda col: col.map(lambda x: f'{x:,.0f}'.replace(',', '.'))) - totals_porc = (pd.crosstab(values=df.factor_expansion_linea, columns=df.Genero, index=df.Tarifa, aggfunc='sum', margins=True, margins_name='Total', normalize=True) * 100).round(2) - - modos = socio_indicadores[socio_indicadores.tabla=='etapas-genero-modo'].copy() - modos_genero_abs = pd.crosstab(values=modos.factor_expansion_linea, index=[modos.Genero], columns=modos.Modo, aggfunc='sum', normalize=False, margins=True, margins_name='Total').fillna(0).astype(int).apply(lambda col: col.map(lambda x: f'{x:,.0f}'.replace(',', '.'))) - modos_genero_porc = (pd.crosstab(values=modos.factor_expansion_linea, index=modos.Genero, columns=modos.Modo, aggfunc='sum', normalize=True, margins=True, margins_name='Total') * 100).round(2) + totals = None + totals_porc = 0 + avg_distances = 0 + avg_times = 0 + avg_velocity = 0 + modos_genero_abs = 0 + modos_genero_porc = 0 + modos_tarifa_abs = 0 + modos_tarifa_porc = 0 + avg_viajes = 0 + avg_etapas = 0 + avg_tiempo_entre_viajes = 0 + + if len(socio_indicadores) > 0: + + df = socio_indicadores[socio_indicadores.tabla=='viajes-genero-tarifa'].copy() + totals = pd.crosstab(values=df.factor_expansion_linea, columns=df.Genero, index=df.Tarifa, aggfunc='sum', margins=True, margins_name='Total', normalize=False).fillna(0).round().astype(int).apply(lambda col: col.map(lambda x: f'{x:,.0f}'.replace(',', '.'))) + totals_porc = (pd.crosstab(values=df.factor_expansion_linea, columns=df.Genero, index=df.Tarifa, aggfunc='sum', margins=True, margins_name='Total', normalize=True) * 100).round(2) + + modos = socio_indicadores[socio_indicadores.tabla=='etapas-genero-modo'].copy() + modos_genero_abs = pd.crosstab(values=modos.factor_expansion_linea, index=[modos.Genero], columns=modos.Modo, aggfunc='sum', normalize=False, margins=True, margins_name='Total').fillna(0).astype(int).apply(lambda col: col.map(lambda x: f'{x:,.0f}'.replace(',', '.'))) + modos_genero_porc = (pd.crosstab(values=modos.factor_expansion_linea, index=modos.Genero, columns=modos.Modo, aggfunc='sum', normalize=True, margins=True, margins_name='Total') * 100).round(2) + + modos = socio_indicadores[socio_indicadores.tabla=='etapas-tarifa-modo'].copy() + modos_tarifa_abs = pd.crosstab(values=modos.factor_expansion_linea, index=[modos.Tarifa], columns=modos.Modo, aggfunc='sum', normalize=False, margins=True, margins_name='Total').fillna(0).astype(int).apply(lambda col: col.map(lambda x: f'{x:,.0f}'.replace(',', '.'))) + modos_tarifa_porc = (pd.crosstab(values=modos.factor_expansion_linea, index=modos.Tarifa, columns=modos.Modo, aggfunc='sum', normalize=True, margins=True, margins_name='Total') * 100).round(2) + + avg_distances = pd.crosstab(values=df.Distancia, columns=df.Genero, index=df.Tarifa, margins=True, margins_name='Total',aggfunc=lambda x: (x * df.loc[x.index, 'factor_expansion_linea']).sum() / df.loc[x.index, 'factor_expansion_linea'].sum(), ).fillna(0).round(2) + avg_times = pd.crosstab(values=df['Tiempo de viaje'], columns=df.Genero, index=df.Tarifa, margins=True, margins_name='Total',aggfunc=lambda x: (x * df.loc[x.index, 'factor_expansion_linea']).sum() / df.loc[x.index, 'factor_expansion_linea'].sum(), ).fillna(0).round(2) + avg_velocity = pd.crosstab(values=df['Velocidad'], columns=df.Genero, index=df.Tarifa, margins=True, margins_name='Total',aggfunc=lambda x: (x * df.loc[x.index, 'factor_expansion_linea']).sum() / df.loc[x.index, 'factor_expansion_linea'].sum(), ).fillna(0).round(2) + avg_etapas = pd.crosstab(values=df['Etapas promedio'], columns=df.Genero, index=df.Tarifa, margins=True, margins_name='Total',aggfunc=lambda x: (x * df.loc[x.index, 'factor_expansion_linea']).sum() / df.loc[x.index, 'factor_expansion_linea'].sum(), ).round(2).fillna('') + user = socio_indicadores[socio_indicadores.tabla=='usuario-genero-tarifa'].copy() + avg_viajes = pd.crosstab(values=user['Viajes promedio'], + index=[user.Tarifa], + columns=user.Genero, + margins=True, + margins_name='Total', + aggfunc=lambda x: (x * user.loc[x.index, 'factor_expansion_linea']).sum() / user.loc[x.index, 'factor_expansion_linea'].sum(),).round(2).fillna('') - modos = socio_indicadores[socio_indicadores.tabla=='etapas-tarifa-modo'].copy() - modos_tarifa_abs = pd.crosstab(values=modos.factor_expansion_linea, index=[modos.Tarifa], columns=modos.Modo, aggfunc='sum', normalize=False, margins=True, margins_name='Total').fillna(0).astype(int).apply(lambda col: col.map(lambda x: f'{x:,.0f}'.replace(',', '.'))) - modos_tarifa_porc = (pd.crosstab(values=modos.factor_expansion_linea, index=modos.Tarifa, columns=modos.Modo, aggfunc='sum', normalize=True, margins=True, margins_name='Total') * 100).round(2) - - avg_distances = pd.crosstab(values=df.Distancia, columns=df.Genero, index=df.Tarifa, margins=True, margins_name='Total',aggfunc=lambda x: (x * df.loc[x.index, 'factor_expansion_linea']).sum() / df.loc[x.index, 'factor_expansion_linea'].sum(), ).fillna(0).round(2) - avg_times = pd.crosstab(values=df['Tiempo de viaje'], columns=df.Genero, index=df.Tarifa, margins=True, margins_name='Total',aggfunc=lambda x: (x * df.loc[x.index, 'factor_expansion_linea']).sum() / df.loc[x.index, 'factor_expansion_linea'].sum(), ).fillna(0).round(2) - avg_velocity = pd.crosstab(values=df['Velocidad'], columns=df.Genero, index=df.Tarifa, margins=True, margins_name='Total',aggfunc=lambda x: (x * df.loc[x.index, 'factor_expansion_linea']).sum() / df.loc[x.index, 'factor_expansion_linea'].sum(), ).fillna(0).round(2) - avg_etapas = pd.crosstab(values=df['Etapas promedio'], columns=df.Genero, index=df.Tarifa, margins=True, margins_name='Total',aggfunc=lambda x: (x * df.loc[x.index, 'factor_expansion_linea']).sum() / df.loc[x.index, 'factor_expansion_linea'].sum(), ).round(2).fillna('') - user = socio_indicadores[socio_indicadores.tabla=='usuario-genero-tarifa'].copy() - avg_viajes = pd.crosstab(values=user['Viajes promedio'], index=[user.Tarifa], columns=user.Genero, margins=True, margins_name='Total', aggfunc=lambda x: (x * user.loc[x.index, 'factor_expansion_linea']).sum() / user.loc[x.index, 'factor_expansion_linea'].sum(),).round(2).fillna('') - - avg_tiempo_entre_viajes = pd.crosstab(values=df['Tiempo entre viajes'], columns=df.Genero, index=df.Tarifa, margins=True, margins_name='Total',aggfunc=lambda x: (x * df.loc[x.index, 'factor_expansion_linea']).sum() / df.loc[x.index, 'factor_expansion_linea'].sum(), ).fillna(0).round(2) + avg_tiempo_entre_viajes = pd.crosstab(values=df['Tiempo entre viajes'], + columns=df.Genero, + index=df.Tarifa, + margins=True, + margins_name='Total', + aggfunc=lambda x: (x * df.loc[x.index, 'factor_expansion_linea']).sum() / df.loc[x.index, 'factor_expansion_linea'].sum(), ).fillna(0).round(2) return totals, totals_porc, avg_distances, avg_times, avg_velocity, modos_genero_abs, modos_genero_porc, modos_tarifa_abs, modos_tarifa_porc, avg_viajes, avg_etapas, avg_tiempo_entre_viajes @@ -315,20 +340,18 @@ def hay_cambios_en_filtros(current, last): st.session_state[var] = '' etapas_lst_ = levanto_tabla_sql('agg_etapas', 'dash', 'SELECT DISTINCT mes FROM agg_etapas;') - - - # st.session_state.etapas = traigo() - + if len(etapas_lst_) > 0: zonificaciones = levanto_tabla_sql('zonificaciones') socio_indicadores = levanto_tabla_sql('socio_indicadores') desc_tipo_dia_ = levanto_tabla_sql('agg_etapas', 'dash', 'SELECT DISTINCT tipo_dia FROM agg_etapas;') - desc_zona_ = levanto_tabla_sql('agg_etapas', 'dash', 'SELECT DISTINCT zona FROM agg_etapas;') + desc_zona_ = levanto_tabla_sql('agg_etapas', 'dash', 'SELECT DISTINCT zona FROM agg_etapas;').sort_values('zona') modos_list_all_ = levanto_tabla_sql('agg_etapas', 'dash', 'SELECT DISTINCT modo_agregado FROM agg_etapas;') rango_hora_all_ = levanto_tabla_sql('agg_etapas', 'dash', 'SELECT DISTINCT rango_hora FROM agg_etapas;') distancia_all_ = levanto_tabla_sql('agg_etapas', 'dash', 'SELECT DISTINCT distancia FROM agg_etapas;') - + zonas_values = traigo_zonas_values('etapas') + # st.session_state.etapas_all = st.session_state.etapas_all[st.session_state.etapas_all.factor_expansion_linea > 0].copy() general, modal, distancias = traigo_indicadores('all') @@ -342,7 +365,8 @@ def hay_cambios_en_filtros(current, last): 'transferencia': 'Todos', 'modo_agregado': 'Todos', 'rango_hora': 'Todos', - 'distancia': 'Todas' + 'distancia': 'Todas', + 'desc_zonas_values':'Todos' } if 'data_cargada' not in st.session_state: @@ -362,7 +386,6 @@ def hay_cambios_en_filtros(current, last): modos_list = col1.selectbox('Modos', options=[text for text in modos_list_all]) rango_hora_all = ['Todos'] + rango_hora_all_[rango_hora_all_.rango_hora != '99'].rango_hora.unique().tolist() - # rango_hora = col1.selectbox('Rango hora', options=[text.capitalize() for text in rango_hora_all]) rango_hora = col1.selectbox('Rango hora', options=[text for text in rango_hora_all]) distancia_all = ['Todas'] + distancia_all_[distancia_all_.distancia != '99'].distancia.unique().tolist() @@ -379,6 +402,10 @@ def hay_cambios_en_filtros(current, last): desc_viajes = False desc_etapas = False + zonas_values_all = ['Todos'] + zonas_values[zonas_values.zona == desc_zona].Nombre.unique().tolist() + desc_zonas_values = col1.selectbox('Filtro', options=zonas_values_all) + + desc_origenes = col1.checkbox( ':blue[Origenes]', value=False) @@ -394,6 +421,8 @@ def hay_cambios_en_filtros(current, last): zonif = zonificaciones[zonificaciones.zona == desc_zona] else: zonif = '' + + mtabla = col2.checkbox('Mostrar tabla', value=False) # Construye el diccionario de filtros actual current_filters = { @@ -404,6 +433,7 @@ def hay_cambios_en_filtros(current, last): 'modo_agregado': None if modos_list == 'Todos' else modos_list, 'rango_hora': None if rango_hora == 'Todos' else rango_hora, 'distancia': None if distancia == 'Todas' else distancia, + 'desc_zonas_values': None if desc_zonas_values == 'Todos' else desc_zonas_values, } current_options = { 'desc_etapas': desc_etapas, @@ -412,7 +442,8 @@ def hay_cambios_en_filtros(current, last): 'desc_destinos': desc_destinos, 'desc_et_vi': desc_et_vi, 'desc_transferencias': desc_transferencias, - 'desc_zonif': desc_zonif, } + 'desc_zonif': desc_zonif, + 'mtabla': mtabla} @@ -420,14 +451,20 @@ def hay_cambios_en_filtros(current, last): if hay_cambios_en_filtros(current_filters, st.session_state.last_filters): query = "" - conditions = " AND ".join(f"{key} = '{value}'" for key, value in current_filters.items() if value is not None) + conditions = " AND ".join(f"{key} = '{value}'" for key, value in current_filters.items() if (value is not None)&(key != 'desc_zonas_values')) if conditions: query += f" WHERE {conditions}" - st.session_state.matrices_ = levanto_tabla_sql_local('agg_matrices', tabla_tipo='dash', query=f"SELECT * FROM agg_matrices{query}") - st.session_state.etapas_ = levanto_tabla_sql_local('agg_etapas', tabla_tipo='dash', query=f"SELECT * FROM agg_etapas{query}") - + conditions_etapas = '' + conditions_matrices = '' + if desc_zonas_values != 'Todos': + conditions_etapas = f" AND (inicio_norm = '{desc_zonas_values}' OR transfer1_norm = '{desc_zonas_values}' OR transfer2_norm = '{desc_zonas_values}' OR fin_norm = '{desc_zonas_values}')" + conditions_matrices = f" AND (inicio = '{desc_zonas_values}' OR fin = '{desc_zonas_values}')" + query_etapas = query + conditions_etapas + query_matrices = query + conditions_matrices + st.session_state.etapas_ = levanto_tabla_sql_local('agg_etapas', tabla_tipo='dash', query=f"SELECT * FROM agg_etapas{query_etapas}") + st.session_state.matrices_ = levanto_tabla_sql_local('agg_matrices', tabla_tipo='dash', query=f"SELECT * FROM agg_matrices{query_matrices}") if len(st.session_state.matrices_)==0: col2.write('No hay datos para mostrar') @@ -587,6 +624,9 @@ def hay_cambios_en_filtros(current, last): with col2: folium_static(st.session_state.map, width=1000, height=800) # output = st_folium(st.session_state.map, width=1000, height=800, key='m', returned_objects=["center"]) + if mtabla: + col2.dataframe(st.session_state.etapas_[['inicio_norm', 'transfer1_norm', 'transfer2_norm', 'fin_norm', 'factor_expansion_linea']]) # + else: col2.text("No hay datos suficientes para mostrar el mapa.") else: @@ -660,37 +700,41 @@ def hay_cambios_en_filtros(current, last): col1, col2, col3, col4 = st.columns([1, 2, 2, 2]) totals, totals_porc, avg_distances, avg_times, avg_velocity, modos_genero_abs, modos_genero_porc, modos_tarifa_abs, modos_tarifa_porc, avg_viajes, avg_etapas, avg_tiempo_entre_viajes = traigo_socio_indicadores(st.session_state.socio_indicadores_) - col2.markdown("

Total de viajes por género y tarifa

", unsafe_allow_html=True) - col2.table(totals) - col3.markdown("

Porcentaje de viajes por género y tarifa

", unsafe_allow_html=True) - col3.table(totals_porc.round(2).astype(str)) - - col2.markdown("

Cantidad promedio de viajes por género y tarifa

", unsafe_allow_html=True) - col2.table(avg_viajes.round(2).astype(str)) - col3.markdown("

Cantidad promedio de etapas por género y tarifa

", unsafe_allow_html=True) - col3.table(avg_etapas.round(2).astype(str)) + if totals is not None: + col2.markdown("

Total de viajes por género y tarifa

", unsafe_allow_html=True) + col2.table(totals) + col3.markdown("

Porcentaje de viajes por género y tarifa

", unsafe_allow_html=True) + col3.table(totals_porc.round(2).astype(str)) - col2.markdown("

Total de etapas por género y modo

", unsafe_allow_html=True) - col2.table(modos_genero_abs) - col3.markdown("

Porcentaje de etapas por género y modo

", unsafe_allow_html=True) - col3.table(modos_genero_porc.round(2).astype(str)) - - col2.markdown("

Total de etapas por tarifa y modo

", unsafe_allow_html=True) - col2.table(modos_tarifa_abs) - col3.markdown("

Porcentaje de etapas por tarifa y modo

", unsafe_allow_html=True) - col3.table(modos_tarifa_porc.round(2).astype(str)) - - col2.markdown("

Distancias promedio (kms)

", unsafe_allow_html=True) - col2.table(avg_distances.round(2).astype(str)) - - col3.markdown("

Tiempos promedio (minutos)

", unsafe_allow_html=True) - col3.table(avg_times.round(2).astype(str)) - - col2.markdown("

Velocidades promedio (kms/hora)

", unsafe_allow_html=True) - col2.table(avg_velocity.round(2).astype(str)) - - col3.markdown("

Tiempos promedio entre viajes (minutos)

", unsafe_allow_html=True) - col3.table(avg_tiempo_entre_viajes.round(2).astype(str)) + col2.markdown("

Cantidad promedio de viajes por género y tarifa

", unsafe_allow_html=True) + col2.table(avg_viajes.round(2).astype(str)) + col3.markdown("

Cantidad promedio de etapas por género y tarifa

", unsafe_allow_html=True) + col3.table(avg_etapas.round(2).astype(str)) + + + col2.markdown("

Total de etapas por género y modo

", unsafe_allow_html=True) + col2.table(modos_genero_abs) + col3.markdown("

Porcentaje de etapas por género y modo

", unsafe_allow_html=True) + col3.table(modos_genero_porc.round(2).astype(str)) + + col2.markdown("

Total de etapas por tarifa y modo

", unsafe_allow_html=True) + col2.table(modos_tarifa_abs) + col3.markdown("

Porcentaje de etapas por tarifa y modo

", unsafe_allow_html=True) + col3.table(modos_tarifa_porc.round(2).astype(str)) + + col2.markdown("

Distancias promedio (kms)

", unsafe_allow_html=True) + col2.table(avg_distances.round(2).astype(str)) + + col3.markdown("

Tiempos promedio (minutos)

", unsafe_allow_html=True) + col3.table(avg_times.round(2).astype(str)) + + col2.markdown("

Velocidades promedio (kms/hora)

", unsafe_allow_html=True) + col2.table(avg_velocity.round(2).astype(str)) + + col3.markdown("

Tiempos promedio entre viajes (minutos)

", unsafe_allow_html=True) + col3.table(avg_tiempo_entre_viajes.round(2).astype(str)) + else: + col2.write('No hay datos para mostrar') diff --git a/urbantrips/dashboard/pages/4_Poligonos.py b/urbantrips/dashboard/pages/4_Poligonos.py index 2a56783..43b82e2 100644 --- a/urbantrips/dashboard/pages/4_Poligonos.py +++ b/urbantrips/dashboard/pages/4_Poligonos.py @@ -11,8 +11,8 @@ levanto_tabla_sql, get_logo, create_data_folium, traigo_indicadores, extract_hex_colors_from_cmap, - iniciar_conexion_db, normalize_vars - + iniciar_conexion_db, normalize_vars, + traigo_zonas_values ) from streamlit_folium import folium_static @@ -297,12 +297,12 @@ def hay_cambios_en_filtros(current, last): zonificaciones = levanto_tabla_sql('zonificaciones') socio_indicadores = levanto_tabla_sql('socio_indicadores') desc_tipo_dia_ = levanto_tabla_sql('poly_etapas', 'dash', 'SELECT DISTINCT tipo_dia FROM poly_etapas;') - desc_zona_ = levanto_tabla_sql('poly_etapas', 'dash', 'SELECT DISTINCT zona FROM poly_etapas;') + desc_zona_ = levanto_tabla_sql('poly_etapas', 'dash', 'SELECT DISTINCT zona FROM poly_etapas;').sort_values('zona') modos_list_all_ = levanto_tabla_sql('poly_etapas', 'dash', 'SELECT DISTINCT modo_agregado FROM poly_etapas;') rango_hora_all_ = levanto_tabla_sql('poly_etapas', 'dash', 'SELECT DISTINCT rango_hora FROM poly_etapas;') distancia_all_ = levanto_tabla_sql('poly_etapas', 'dash', 'SELECT DISTINCT distancia FROM poly_etapas;') desc_poly_all_ = levanto_tabla_sql('poly_etapas', 'dash', 'SELECT DISTINCT id_polygon FROM poly_etapas;') - + zonas_values = traigo_zonas_values('poligonos') # st.session_state.etapas_all = st.session_state.etapas_all[st.session_state.etapas_all.factor_expansion_linea > 0].copy() general, modal, distancias = traigo_indicadores('poligonos') @@ -316,11 +316,13 @@ def hay_cambios_en_filtros(current, last): 'transferencia': 'Todos', 'modo_agregado': 'Todos', 'rango_hora': 'Todos', - 'distancia': 'Todas' + 'distancia': 'Todas', + 'desc_zonas_values':'Todos' } if 'data_cargada' not in st.session_state: st.session_state.data_cargada = False + # Opciones de los filtros en Streamlit # st.session_state.etapas_lst = ['Todos'] + etapas_lst_.mes.unique().tolist() @@ -358,6 +360,9 @@ def hay_cambios_en_filtros(current, last): desc_viajes = False desc_etapas = False + zonas_values_all = ['Todos'] + zonas_values[zonas_values.zona == desc_zona].Nombre.unique().tolist() + desc_zonas_values = col1.selectbox('Filtro', options=zonas_values_all) + desc_origenes = col1.checkbox( ':blue[Origenes]', value=False) @@ -383,7 +388,7 @@ def hay_cambios_en_filtros(current, last): desc_cuenca = False - + mtabla = col2.checkbox('Mostrar tabla', value=False) # Construye el diccionario de filtros actual current_filters = { @@ -396,6 +401,7 @@ def hay_cambios_en_filtros(current, last): 'distancia': None if distancia == 'Todas' else distancia, 'coincidencias': None if desc_cuenca == False else True, 'id_polygon': st.session_state.desc_poly, + 'desc_zonas_values': None if desc_zonas_values == 'Todos' else desc_zonas_values, } current_options = { 'desc_etapas': desc_etapas, 'desc_viajes': desc_viajes, @@ -404,7 +410,8 @@ def hay_cambios_en_filtros(current, last): 'desc_zonif': desc_zonif, 'show_poly' : st.session_state.show_poly, 'desc_cuenca': desc_cuenca, - 'desc_et_vi': desc_et_vi + 'desc_et_vi': desc_et_vi, + 'mtabla': mtabla } @@ -413,12 +420,22 @@ def hay_cambios_en_filtros(current, last): if hay_cambios_en_filtros(current_filters, st.session_state.last_filters): query = "" - conditions = " AND ".join(f"{key} = '{value}'" for key, value in current_filters.items() if value is not None) + conditions = " AND ".join(f"{key} = '{value}'" for key, value in current_filters.items() if (value is not None)&(key != 'desc_zonas_values')) if conditions: query += f" WHERE {conditions}" + + conditions_etapas = '' + conditions_matrices = '' + if desc_zonas_values != 'Todos': + conditions_etapas = f" AND (inicio_norm = '{desc_zonas_values}' OR transfer1_norm = '{desc_zonas_values}' OR transfer2_norm = '{desc_zonas_values}' OR fin_norm = '{desc_zonas_values}')" + conditions_matrices = f" AND (inicio = '{desc_zonas_values}' OR fin = '{desc_zonas_values}')" + query_etapas = query + conditions_etapas + query_matrices = query + conditions_matrices + + + st.session_state.etapas_ = levanto_tabla_sql_local('poly_etapas', tabla_tipo='dash', query=f"SELECT * FROM poly_etapas{query_etapas}") + st.session_state.matrices_ = levanto_tabla_sql_local('poly_matrices', tabla_tipo='dash', query=f"SELECT * FROM poly_matrices{query_matrices}") - st.session_state.matrices_ = levanto_tabla_sql_local('poly_matrices', tabla_tipo='dash', query=f"SELECT * FROM poly_matrices{query}") - st.session_state.etapas_ = levanto_tabla_sql_local('poly_etapas', tabla_tipo='dash', query=f"SELECT * FROM poly_etapas{query}") if len(st.session_state.etapas_)==0: col2.write('No hay datos para mostrar') @@ -531,6 +548,12 @@ def hay_cambios_en_filtros(current, last): if st.session_state.map: with col2: folium_static(st.session_state.map, width=1000, height=800) + + + if mtabla: + col2.dataframe(st.session_state.etapas_[['inicio_norm', 'transfer1_norm', 'transfer2_norm', 'fin_norm', 'factor_expansion_linea']]) + + else: col2.text("No hay datos suficientes para mostrar el mapa.") diff --git "a/urbantrips/dashboard/pages/5_An\303\241lisis de zonas.py" "b/urbantrips/dashboard/pages/5_An\303\241lisis de zonas.py" index 3f58e68..18f6c69 100644 --- "a/urbantrips/dashboard/pages/5_An\303\241lisis de zonas.py" +++ "b/urbantrips/dashboard/pages/5_An\303\241lisis de zonas.py" @@ -136,86 +136,89 @@ def main(): ## Etapas query1 = f"SELECT * FROM etapas_agregadas WHERE mes = '{desc_mes}' AND tipo_dia = '{desc_tipo_dia}' AND (h3_o IN ({h3_values1}));" etapas1 = levanto_tabla_sql_local('etapas_agregadas', tabla_tipo='dash', query=query1) - etapas1['Zona_1'] = 'Zona 1' - ## Viajes - query1 = f"SELECT * FROM viajes_agregados WHERE mes = '{desc_mes}' AND tipo_dia = '{desc_tipo_dia}' AND (h3_o IN ({h3_values1}) );" - viajes1 = levanto_tabla_sql_local('viajes_agregados', tabla_tipo='dash', query=query1) - viajes1['Zona_1'] = 'Zona 1' - - modos_e1 = etapas1.groupby(['modo', 'nombre_linea'], as_index=False).factor_expansion_linea.sum().rename(columns={'factor_expansion_linea':'Etapas', - 'nombre_linea': 'Línea', 'modo': 'Modo'}) - - modos_v1 = viajes1.groupby(['modo'], as_index=False).factor_expansion_linea.sum().rename(columns={'factor_expansion_linea':'Viajes', - 'modo': 'Modo'}) - - # Calculate the total and append as a new row - total_row1e = pd.DataFrame({ - 'Modo': ['Total'], - 'Línea': ['-'], - 'Etapas': [modos_e1['Etapas'].sum()] - }) - modos_e1 = pd.concat([modos_e1, total_row1e], ignore_index=True) - - - # Calculate the total and append as a new row - total_row1 = pd.DataFrame({ - 'Modo': ['Total'], - 'Viajes': [modos_v1['Viajes'].sum()] - }) - modos_v1 = pd.concat([modos_v1, total_row1], ignore_index=True) - - col2.title('Zona 1') - col2.write('Etapas') - modos_e1['Etapas'] = modos_e1['Etapas'].round() - col2.dataframe(modos_e1.set_index('Modo'), height=400, width=400) - col3.title('') - col3.write('Viajes') - modos_v1['Viajes'] = modos_v1['Viajes'].round() - col3.dataframe(modos_v1.set_index('Modo'), height=400, width=300) + if len(etapas1) > 0: + etapas1['Zona_1'] = 'Zona 1' + + ## Viajes + query1 = f"SELECT * FROM viajes_agregados WHERE mes = '{desc_mes}' AND tipo_dia = '{desc_tipo_dia}' AND (h3_o IN ({h3_values1}) );" + viajes1 = levanto_tabla_sql_local('viajes_agregados', tabla_tipo='dash', query=query1) + viajes1['Zona_1'] = 'Zona 1' + + modos_e1 = etapas1.groupby(['modo', 'nombre_linea'], as_index=False).factor_expansion_linea.sum().rename(columns={'factor_expansion_linea':'Etapas', + 'nombre_linea': 'Línea', 'modo': 'Modo'}) + + modos_v1 = viajes1.groupby(['modo'], as_index=False).factor_expansion_linea.sum().rename(columns={'factor_expansion_linea':'Viajes', + 'modo': 'Modo'}) + + # Calculate the total and append as a new row + total_row1e = pd.DataFrame({ + 'Modo': ['Total'], + 'Línea': ['-'], + 'Etapas': [modos_e1['Etapas'].sum()] + }) + modos_e1 = pd.concat([modos_e1, total_row1e], ignore_index=True) + + + # Calculate the total and append as a new row + total_row1 = pd.DataFrame({ + 'Modo': ['Total'], + 'Viajes': [modos_v1['Viajes'].sum()] + }) + modos_v1 = pd.concat([modos_v1, total_row1], ignore_index=True) + + col2.title('Zona 1') + col2.write('Etapas') + modos_e1['Etapas'] = modos_e1['Etapas'].round() + col2.dataframe(modos_e1.set_index('Modo'), height=400, width=400) + col3.title('') + col3.write('Viajes') + modos_v1['Viajes'] = modos_v1['Viajes'].round() + col3.dataframe(modos_v1.set_index('Modo'), height=400, width=300) if len(zona2) > 0: h3_values2 = ", ".join(f"'{item}'" for item in zona2) ## Etapas query2 = f"SELECT * FROM etapas_agregadas WHERE mes = '{desc_mes}' AND tipo_dia = '{desc_tipo_dia}' AND (h3_o IN ({h3_values2}));" etapas2 = levanto_tabla_sql_local('etapas_agregadas', tabla_tipo='dash', query=query2) - etapas2['Zona_2'] = 'Zona 2' - - ## Viajes - query2 = f"SELECT * FROM viajes_agregados WHERE mes = '{desc_mes}' AND tipo_dia = '{desc_tipo_dia}' AND (h3_o IN ({h3_values2}) );" - viajes2 = levanto_tabla_sql_local('viajes_agregados', tabla_tipo='dash', query=query2) - viajes2['Zona_2'] = 'Zona 2' - - modos_e2 = etapas2.groupby(['modo', 'nombre_linea'], as_index=False).factor_expansion_linea.sum().rename(columns={'factor_expansion_linea':'Etapas', - 'nombre_linea': 'Línea', 'modo': 'Modo'}) - - modos_v2 = viajes2.groupby(['modo'], as_index=False).factor_expansion_linea.sum().rename(columns={'factor_expansion_linea':'Viajes', - 'modo': 'Modo'}) - # Calculate the total and append as a new row - total_row2e = pd.DataFrame({ - 'Modo': ['Total'], - 'Línea': ['-'], - 'Etapas': [modos_e2['Etapas'].sum()] - }) - modos_e2 = pd.concat([modos_e2, total_row2e], ignore_index=True) - - # Calculate the total and append as a new row - total_row2 = pd.DataFrame({ - 'Modo': ['Total'], - 'Viajes': [modos_v2['Viajes'].sum()] - }) - modos_v2 = pd.concat([modos_v2, total_row2], ignore_index=True) - - - col4.title('Zona 2') - col4.write('Etapas') - modos_e2['Etapas'] = modos_e2['Etapas'].round() - col4.dataframe(modos_e2.set_index('Modo'), height=400, width=400) - - modos_v2['Viajes'] = modos_v2['Viajes'].round() - col5.title('') - col5.write('Viajes') - # col5.markdown(modos_v2.to_html(index=False), unsafe_allow_html=True) - col5.dataframe(modos_v2.set_index('Modo'), height=400, width=300) + if len(etapas2) > 0: + etapas2['Zona_2'] = 'Zona 2' + + ## Viajes + query2 = f"SELECT * FROM viajes_agregados WHERE mes = '{desc_mes}' AND tipo_dia = '{desc_tipo_dia}' AND (h3_o IN ({h3_values2}) );" + viajes2 = levanto_tabla_sql_local('viajes_agregados', tabla_tipo='dash', query=query2) + viajes2['Zona_2'] = 'Zona 2' + + modos_e2 = etapas2.groupby(['modo', 'nombre_linea'], as_index=False).factor_expansion_linea.sum().rename(columns={'factor_expansion_linea':'Etapas', + 'nombre_linea': 'Línea', 'modo': 'Modo'}) + + modos_v2 = viajes2.groupby(['modo'], as_index=False).factor_expansion_linea.sum().rename(columns={'factor_expansion_linea':'Viajes', + 'modo': 'Modo'}) + # Calculate the total and append as a new row + total_row2e = pd.DataFrame({ + 'Modo': ['Total'], + 'Línea': ['-'], + 'Etapas': [modos_e2['Etapas'].sum()] + }) + modos_e2 = pd.concat([modos_e2, total_row2e], ignore_index=True) + + # Calculate the total and append as a new row + total_row2 = pd.DataFrame({ + 'Modo': ['Total'], + 'Viajes': [modos_v2['Viajes'].sum()] + }) + modos_v2 = pd.concat([modos_v2, total_row2], ignore_index=True) + + + col4.title('Zona 2') + col4.write('Etapas') + modos_e2['Etapas'] = modos_e2['Etapas'].round() + col4.dataframe(modos_e2.set_index('Modo'), height=400, width=400) + + modos_v2['Viajes'] = modos_v2['Viajes'].round() + col5.title('') + col5.write('Viajes') + # col5.markdown(modos_v2.to_html(index=False), unsafe_allow_html=True) + col5.dataframe(modos_v2.set_index('Modo'), height=400, width=300) with st.expander('Viajes entre zonas', expanded=True): col1, col2, col3, col4 = st.columns([1, 2, 2, 3]) @@ -225,90 +228,123 @@ def main(): ## Etapas query = f"SELECT * FROM etapas_agregadas WHERE mes = '{desc_mes}' AND tipo_dia = '{desc_tipo_dia}' AND (h3_o IN ({h3_values}) OR h3_d IN ({h3_values}));" etapas = levanto_tabla_sql_local('etapas_agregadas', tabla_tipo='dash', query=query) - - etapas['Zona_1'] = '' - etapas['Zona_2'] = '' - etapas.loc[etapas.h3_o.isin(zona1), 'Zona_1'] = 'Zona 1' - etapas.loc[etapas.h3_o.isin(zona2), 'Zona_1'] = 'Zona 2' - etapas.loc[etapas.h3_d.isin(zona1), 'Zona_2'] = 'Zona 1' - etapas.loc[etapas.h3_d.isin(zona2), 'Zona_2'] = 'Zona 2' - etapas = etapas[(etapas.Zona_1 != '') & (etapas.Zona_2 != '') & (etapas.Zona_1 != etapas.Zona_2) & (etapas.Zona_1 != etapas.Zona_2)] - - etapas = etapas.fillna('') - - zonasod_e = etapas.groupby(['Zona_1', 'Zona_2'], as_index=False).factor_expansion_linea.sum().rename(columns={'factor_expansion_linea':'Etapas'}) - - modos_e = etapas.groupby(['modo', 'nombre_linea'], as_index=False).factor_expansion_linea.sum().rename(columns={'factor_expansion_linea':'Etapas', - 'nombre_linea': 'Línea', - 'modo': 'Modo'}) - # Calculate the total and append as a new row - total_rowe = pd.DataFrame({ - 'Modo': ['Total'], - 'Línea': ['-'], - 'Etapas': [modos_e['Etapas'].sum()] - }) - modos_e = pd.concat([modos_e, total_rowe], ignore_index=True) - - modos_e['Etapas'] = modos_e['Etapas'].round() + if len(etapas) > 0: - col2.write('Etapas') - col2.markdown(zonasod_e.to_html(index=False), unsafe_allow_html=True) - col2.dataframe(modos_e.set_index('Modo'), height=500, width=400) - - - ## Viajes - query = f"SELECT * FROM viajes_agregados WHERE mes = '{desc_mes}' AND tipo_dia = '{desc_tipo_dia}' AND (h3_o IN ({h3_values}) OR h3_d IN ({h3_values}));" - viajes = levanto_tabla_sql_local('viajes_agregados', tabla_tipo='dash', query=query) + etapas['Zona_1'] = '' + etapas['Zona_2'] = '' + etapas.loc[etapas.h3_o.isin(zona1), 'Zona_1'] = 'Zona 1' + etapas.loc[etapas.h3_o.isin(zona2), 'Zona_1'] = 'Zona 2' + etapas.loc[etapas.h3_d.isin(zona1), 'Zona_2'] = 'Zona 1' + etapas.loc[etapas.h3_d.isin(zona2), 'Zona_2'] = 'Zona 2' + etapas = etapas[(etapas.Zona_1 != '') & (etapas.Zona_2 != '') & (etapas.Zona_1 != etapas.Zona_2)] + + etapas = etapas.fillna('') + + zonasod_e = etapas.groupby(['Zona_1', 'Zona_2'], as_index=False).factor_expansion_linea.sum().rename(columns={'factor_expansion_linea':'Etapas'}) + + + modos_e = etapas.groupby(['modo', 'nombre_linea'], as_index=False).factor_expansion_linea.sum().rename(columns={'factor_expansion_linea':'Etapas', + 'nombre_linea': 'Línea', + 'modo': 'Modo'}) + + col2.write(zonasod_e) + + # Calculate the total and append as a new row + total_rowe = pd.DataFrame({ + 'Modo': ['Total'], + 'Línea': ['-'], + 'Etapas': [modos_e['Etapas'].sum()] + }) + modos_e = pd.concat([modos_e, total_rowe], ignore_index=True) + + modos_e['Etapas'] = modos_e['Etapas'].round() + + col2.write('Etapas') + col2.markdown(zonasod_e.to_html(index=False), unsafe_allow_html=True) + col2.dataframe(modos_e.set_index('Modo'), height=500, width=400) + + + ## Viajes + h3_values = ", ".join(f"'{item}'" for item in zona1 + zona2) + query = f"SELECT * FROM viajes_agregados WHERE mes = '{desc_mes}' AND tipo_dia = '{desc_tipo_dia}' AND (h3_o IN ({h3_values}) OR h3_d IN ({h3_values}));" + viajes = levanto_tabla_sql_local('viajes_agregados', tabla_tipo='dash', query=query) + + viajes['Zona_1'] = '' + viajes['Zona_2'] = '' + viajes.loc[viajes.h3_o.isin(zona1), 'Zona_1'] = 'Zona 1' + viajes.loc[viajes.h3_o.isin(zona2), 'Zona_1'] = 'Zona 2' + viajes.loc[viajes.h3_d.isin(zona1), 'Zona_2'] = 'Zona 1' + viajes.loc[viajes.h3_d.isin(zona2), 'Zona_2'] = 'Zona 2' + viajes = viajes[(viajes.Zona_1 != '') & (viajes.Zona_2 != '') & (viajes.Zona_1 != viajes.Zona_2)] + + zonasod_v = viajes.groupby(['Zona_1', 'Zona_2'], as_index=False).factor_expansion_linea.sum().rename(columns={'factor_expansion_linea':'Viajes'}) + + + + modos_v = viajes.groupby(['modo'], as_index=False).factor_expansion_linea.sum().rename(columns={'factor_expansion_linea':'Viajes', + 'modo': 'Modo'}) + + # Calculate the total and append as a new row + total_row = pd.DataFrame({ + 'Modo': ['Total'], + 'Viajes': [modos_v['Viajes'].sum()] + }) + modos_v = pd.concat([modos_v, total_row], ignore_index=True) + + col3.write('Viajes') + col3.markdown(zonasod_v.to_html(index=False), unsafe_allow_html=True) + modos_v['Viajes'] = modos_v['Viajes'].round() + # col3.markdown(modos_v.to_html(index=False), unsafe_allow_html=True) + col3.dataframe(modos_v.set_index('Modo'), height=500, width=300) + + ## Mapa + + # Create unified geometry for each zone + def zona_to_geometry(h3_list): + polygons = [Polygon(h3.h3_to_geo_boundary(h3_index, geo_json=True)) for h3_index in h3_list] + return unary_union(polygons) + + geometry_zona1 = zona_to_geometry(st.session_state['zona_1']) + geometry_zona2 = zona_to_geometry(st.session_state['zona_2']) + gdf = gpd.GeoDataFrame({ + 'zona': ['Zona 1', 'Zona 2'], + 'geometry': [geometry_zona1, geometry_zona2] + }, crs="EPSG:4326") + + # Plot the zones on a new Folium map + m2 = folium.Map(location=[gdf.geometry.centroid.y.mean(), gdf.geometry.centroid.x.mean()], zoom_start=10) + folium.GeoJson(gdf, name="GeoData").add_to(m2) + + with col4: + output2 = st_folium(m2, width=700, height=700) + + with st.expander('Viajes con transferencias', expanded=False): + col1, col2 = st.columns([1, 3]) + ## Transferencias + h3_values = ", ".join(f"'{item}'" for item in zona1 + zona2) + query = f"SELECT * FROM transferencias_agregadas WHERE mes = '{desc_mes}' AND tipo_dia = '{desc_tipo_dia}' AND (h3_o IN ({h3_values}) OR h3_d IN ({h3_values}));" + transferencias = levanto_tabla_sql_local('transferencias_agregadas', tabla_tipo='dash', query=query) + + if len(transferencias) > 0: + + transferencias['Zona_1'] = '' + transferencias['Zona_2'] = '' + transferencias.loc[transferencias.h3_o.isin(zona1), 'Zona_1'] = 'Zona 1' + transferencias.loc[transferencias.h3_o.isin(zona2), 'Zona_1'] = 'Zona 2' + transferencias.loc[transferencias.h3_d.isin(zona1), 'Zona_2'] = 'Zona 1' + transferencias.loc[transferencias.h3_d.isin(zona2), 'Zona_2'] = 'Zona 2' + transferencias = transferencias[(transferencias.Zona_1 != '') & (transferencias.Zona_2 != '') & (transferencias.Zona_1 != transferencias.Zona_2)] - viajes['Zona_1'] = '' - viajes['Zona_2'] = '' - viajes.loc[viajes.h3_o.isin(zona1), 'Zona_1'] = 'Zona 1' - viajes.loc[viajes.h3_o.isin(zona2), 'Zona_1'] = 'Zona 2' - viajes.loc[viajes.h3_d.isin(zona1), 'Zona_2'] = 'Zona 1' - viajes.loc[viajes.h3_d.isin(zona2), 'Zona_2'] = 'Zona 2' - viajes = viajes[(viajes.Zona_1 != '') & (viajes.Zona_2 != '') & (viajes.Zona_1 != viajes.Zona_2) & (viajes.Zona_1 != viajes.Zona_2)] - - zonasod_v = viajes.groupby(['Zona_1', 'Zona_2'], as_index=False).factor_expansion_linea.sum().rename(columns={'factor_expansion_linea':'Viajes'}) - - - - modos_v = viajes.groupby(['modo'], as_index=False).factor_expansion_linea.sum().rename(columns={'factor_expansion_linea':'Viajes', - 'modo': 'Modo'}) + transferencias = transferencias.fillna('') - # Calculate the total and append as a new row - total_row = pd.DataFrame({ - 'Modo': ['Total'], - 'Viajes': [modos_v['Viajes'].sum()] - }) - modos_v = pd.concat([modos_v, total_row], ignore_index=True) + transferencias = transferencias.groupby(['modo', + 'seq_lineas'], as_index=False).factor_expansion_linea.sum().rename(columns={'factor_expansion_linea':'Viajes', + 'modo':'Modo', 'seq_lineas':'Líneas'}).sort_values('Viajes', ascending=False) + transferencias['Viajes'] = transferencias['Viajes'].astype(int) - col3.write('Viajes') - col3.markdown(zonasod_v.to_html(index=False), unsafe_allow_html=True) - modos_v['Viajes'] = modos_v['Viajes'].round() - # col3.markdown(modos_v.to_html(index=False), unsafe_allow_html=True) - col3.dataframe(modos_v.set_index('Modo'), height=500, width=300) - - ## Mapa - - # Create unified geometry for each zone - def zona_to_geometry(h3_list): - polygons = [Polygon(h3.h3_to_geo_boundary(h3_index, geo_json=True)) for h3_index in h3_list] - return unary_union(polygons) - - geometry_zona1 = zona_to_geometry(st.session_state['zona_1']) - geometry_zona2 = zona_to_geometry(st.session_state['zona_2']) - gdf = gpd.GeoDataFrame({ - 'zona': ['Zona 1', 'Zona 2'], - 'geometry': [geometry_zona1, geometry_zona2] - }, crs="EPSG:4326") - - # Plot the zones on a new Folium map - m2 = folium.Map(location=[gdf.geometry.centroid.y.mean(), gdf.geometry.centroid.x.mean()], zoom_start=10) - folium.GeoJson(gdf, name="GeoData").add_to(m2) + col2.dataframe(transferencias.set_index('Modo'), height=500, width=500) - with col4: - output2 = st_folium(m2, width=700, height=700) if __name__ == '__main__': main() diff --git a/urbantrips/lineas_deseo/lineas_deseo.py b/urbantrips/lineas_deseo/lineas_deseo.py index 9d059b5..04599e8 100644 --- a/urbantrips/lineas_deseo/lineas_deseo.py +++ b/urbantrips/lineas_deseo/lineas_deseo.py @@ -800,8 +800,22 @@ def preparo_etapas_agregadas(etapas, viajes): v_agg = viajes.groupby(['dia', 'mes', 'tipo_dia', 'h3_o', 'h3_d', 'modo'], as_index=False).factor_expansion_linea.sum() v_agg = v_agg.groupby(['mes', 'tipo_dia', 'h3_o', 'h3_d', 'modo'], as_index=False).factor_expansion_linea.mean() v_agg = v_agg[v_agg.h3_o!=v_agg.h3_d] + + etapas['etapas_max'] = etapas.groupby(['dia', 'id_tarjeta', 'id_viaje']).id_etapa.transform('max') + transfers = etapas.loc[(etapas.etapas_max>1), ['dia', 'id_tarjeta', 'id_viaje', 'id_etapa', 'etapas_max', 'id_linea', 'h3_o', 'h3_d', 'factor_expansion_linea']] + transfers = transfers.merge(lineas[['id_linea', 'nombre_linea']], how='left') + transfers = transfers.pivot(index=['dia', 'id_tarjeta', 'id_viaje'], columns='id_etapa', values='nombre_linea').reset_index().fillna('') + transfers['seq_lineas'] = '' + for i in range(1, etapas.etapas_max.max()+1): + transfers['seq_lineas'] += transfers[i] + ' -- ' + transfers['seq_lineas'] = transfers['seq_lineas'].str.replace(' -- -- ', '') + + transfers['seq_lineas'] = transfers.seq_lineas.str[:-4] + transfers = viajes.merge(transfers[['dia', 'id_tarjeta', 'id_viaje', 'seq_lineas']]) + transfers = transfers.groupby(['dia', 'mes', 'tipo_dia', 'h3_o', 'h3_d', 'modo', 'seq_lineas'], as_index=False).factor_expansion_linea.sum() + transfers = transfers.groupby(['mes', 'tipo_dia', 'h3_o', 'h3_d', 'modo', 'seq_lineas'], as_index=False).factor_expansion_linea.mean() - return e_agg, v_agg + return e_agg, v_agg, transfers def preparo_lineas_deseo(etapas_selec, viajes_selec, polygons_h3='', poligonos='', res=6): @@ -816,15 +830,17 @@ def preparo_lineas_deseo(etapas_selec, viajes_selec, polygons_h3='', poligonos=' viajes_selec['id_polygon'] = 'NONE' etapas_selec['coincidencias'] = 'NONE' viajes_selec['coincidencias'] = 'NONE' - - etapas_selec = etapas_selec[etapas_selec.distance_osm_drive.notna()].copy() + #### etapas_selec = etapas_selec[etapas_selec.distance_osm_drive.notna()].copy() + etapas_selec = etapas_selec.rename( columns={'distance_osm_drive': 'distance_osm_drive_etapas'}) distancias_all = etapas_selec.groupby( ['id_polygon', 'dia', 'id_tarjeta', 'id_viaje'], as_index=False)[['distance_osm_drive_etapas']].sum() + distancias_all = distancias_all.merge(viajes_selec.loc[viajes_selec.od_validado == 1, [ - 'id_polygon', 'dia', 'id_tarjeta', 'id_viaje', 'distance_osm_drive', 'travel_time_min', 'travel_speed']]) + 'id_polygon', 'dia', 'id_tarjeta', 'id_viaje', 'distance_osm_drive', 'travel_time_min', 'travel_speed']]) # + distancias_all['distancia'] = 'Viajes cortos (<=5kms)' distancias_all.loc[(distancias_all.distance_osm_drive > 5), 'distancia'] = 'Viajes largos (>5kms)' @@ -866,16 +882,11 @@ def preparo_lineas_deseo(etapas_selec, viajes_selec, polygons_h3='', poligonos=' etapas_selec.loc[(etapas_selec.hora >= 17) & ( etapas_selec.hora <= 24), 'rango_hora'] = '17-24' - etapas_agrupadas_all = pd.DataFrame([]) - gpd_viajes_agrupados_all = pd.DataFrame([]) - for id_polygon in polygons_h3.id_polygon.unique(): poly_h3 = polygons_h3[polygons_h3.id_polygon == id_polygon] poly = poligonos[poligonos.id == id_polygon] tipo_poly = poly.tipo.values[0] - print('') - print(f'Polígono {id_polygon} - Tipo: {tipo_poly}') # Preparo Etapas con inicio, transferencias y fin del viaje etapas_all = etapas_selec.loc[(etapas_selec.id_polygon == id_polygon), ['dia', @@ -940,8 +951,7 @@ def preparo_lineas_deseo(etapas_selec, viajes_selec, polygons_h3='', poligonos=' etapas_all = pd.concat([etapas_all, ultimo_viaje]).sort_values( ['dia', 'id_tarjeta', 'id_viaje', 'id_etapa']).reset_index(drop=True) - etapas_all['tipo_viaje'] = 'Transfer_' + \ - (etapas_all['id_etapa']-1).astype(str) + etapas_all['tipo_viaje'] = 'Transfer_' + (etapas_all['id_etapa']-1).astype(str) etapas_all.loc[etapas_all.ultimo_viaje == 1, 'tipo_viaje'] = 'Fin' etapas_all.loc[etapas_all.id_etapa == 1, 'tipo_viaje'] = 'Inicio' @@ -1012,10 +1022,10 @@ def preparo_lineas_deseo(etapas_selec, viajes_selec, polygons_h3='', poligonos=' 'tarifa', 'coincidencias', 'factor_expansion_linea']] - - for zona in zonas: + print('') + print(f'Polígono {id_polygon} - Tipo: {tipo_poly} - Zona: {zona}') if id_polygon != 'NONE': # print(id_polygon, zona) @@ -1136,264 +1146,320 @@ def preparo_lineas_deseo(etapas_selec, viajes_selec, polygons_h3='', poligonos=' etapas_agrupadas_zon = normalizo_zona(etapas_agrupadas_zon, zonificaciones[zonificaciones.zona == zona].copy()) - etapas_agrupadas_all = pd.concat( - [etapas_agrupadas_all, etapas_agrupadas_zon], ignore_index=True) - - etapas_agrupadas_all['transferencia'] = 0 - etapas_agrupadas_all.loc[(etapas_agrupadas_all.transfer1_norm != '') | ( - etapas_agrupadas_all.transfer2_norm != ''), 'transferencia'] = 1 - - etapas_agrupadas_all = etapas_agrupadas_all.merge( - distancias_all, how='left') - - etapas_agrupadas_all['tipo_dia_'] = pd.to_datetime(etapas_agrupadas_all.dia).dt.weekday.astype(str).copy() - etapas_agrupadas_all['tipo_dia'] = 'Hábil' - etapas_agrupadas_all.loc[etapas_agrupadas_all.tipo_dia_.astype(int)>=5, 'tipo_dia'] = 'Fin de Semana' - etapas_agrupadas_all = etapas_agrupadas_all.drop(['tipo_dia_'], axis=1) - etapas_agrupadas_all['mes'] = etapas_agrupadas_all.dia.str[:7] - - etapas_agrupadas_all = etapas_agrupadas_all[['id_polygon', 'zona', 'dia', 'mes', 'tipo_dia', 'id_tarjeta', 'id_viaje', - 'h3_inicio', 'h3_transfer1', 'h3_transfer2', 'h3_fin', - 'inicio', 'transfer1', 'transfer2', 'fin', - 'poly_inicio', 'poly_transfer1', 'poly_transfer2', 'poly_fin', - 'inicio_norm', 'transfer1_norm', 'transfer2_norm', 'fin_norm', - 'poly_inicio_norm', 'poly_transfer1_norm', 'poly_transfer2_norm', 'poly_fin_norm', - 'lon1', 'lat1', 'lon2', 'lat2', 'lon3', 'lat3', 'lon4', 'lat4', - 'lon1_norm', 'lat1_norm', 'lon2_norm', 'lat2_norm', 'lon3_norm', 'lat3_norm', 'lon4_norm', 'lat4_norm', - 'transferencia', 'modo_agregado', 'rango_hora', 'genero', 'tarifa', 'coincidencias', 'distancia', - 'distance_osm_drive', 'distance_osm_drive_etapas', - 'travel_time_min', 'travel_speed', - 'factor_expansion_linea']] - - etapas_sin_agrupar = etapas_agrupadas_all.copy() - - aggregate_cols = ['id_polygon', 'dia', 'mes', 'tipo_dia', 'zona', 'inicio', 'fin', 'poly_inicio', - 'poly_fin', 'transferencia', 'modo_agregado', 'rango_hora', 'genero', 'tarifa', 'coincidencias', 'distancia'] - viajes_matrices = construyo_matrices(etapas_sin_agrupar, - aggregate_cols, - zonificaciones, - False, - False, - False) - - # Agrupación de viajes - aggregate_cols = ['id_polygon', - 'dia', - 'mes', - 'tipo_dia', - 'zona', - 'inicio_norm', - 'transfer1_norm', - 'transfer2_norm', - 'fin_norm', - 'poly_inicio_norm', - 'poly_transfer1_norm', - 'poly_transfer2_norm', - 'poly_fin_norm', - 'transferencia', - 'modo_agregado', - 'rango_hora', - 'genero', - 'tarifa', - 'coincidencias', - 'distancia'] - - weighted_mean_cols = ['distance_osm_drive', - 'distance_osm_drive_etapas', - 'travel_time_min', - 'travel_speed', - 'lat1_norm', - 'lon1_norm', - 'lat2_norm', - 'lon2_norm', - 'lat3_norm', - 'lon3_norm', - 'lat4_norm', - 'lon4_norm'] - - weight_col = 'factor_expansion_linea' - - zero_to_nan = ['lat1_norm', - 'lon1_norm', - 'lat2_norm', - 'lon2_norm', - 'lat3_norm', - 'lon3_norm', - 'lat4_norm', - 'lon4_norm'] - - etapas_agrupadas_all = agrupar_viajes(etapas_agrupadas_all, - aggregate_cols, - weighted_mean_cols, - weight_col, - zero_to_nan, - agg_transferencias=False, - agg_modo=False, - agg_hora=False, - agg_distancia=False) - - zonificaciones['lat'] = zonificaciones.geometry.representative_point().y - zonificaciones['lon'] = zonificaciones.geometry.representative_point().x + ### etapas_agrupadas_zon = pd.concat( + ### [etapas_agrupadas_zon, etapas_agrupadas_zon], ignore_index=True) - n = 1 - poly_lst = ['poly_inicio', 'poly_transfer1', 'poly_transfer2', 'poly_fin'] - for i in ['inicio', 'transfer1', 'transfer2', 'fin']: - etapas_agrupadas_all = etapas_agrupadas_all.merge(zonificaciones[['zona', 'id', 'lat', 'lon']].rename(columns={'id': f'{i}_norm', 'lat': f'lat{n}_norm_tmp', 'lon': f'lon{n}_norm_tmp'}), - how='left', - on=['zona', f'{i}_norm']) - etapas_agrupadas_all.loc[etapas_agrupadas_all[f'{poly_lst[n-1]}_norm'] == '', - f'lat{n}_norm'] = etapas_agrupadas_all.loc[etapas_agrupadas_all[f'{poly_lst[n-1]}_norm'] == '', f'lat{n}_norm_tmp'] - etapas_agrupadas_all.loc[etapas_agrupadas_all[f'{poly_lst[n-1]}_norm'] == '', - f'lon{n}_norm'] = etapas_agrupadas_all.loc[etapas_agrupadas_all[f'{poly_lst[n-1]}_norm'] == '', f'lon{n}_norm_tmp'] - - etapas_agrupadas_all = etapas_agrupadas_all.drop( - [f'lat{n}_norm_tmp', f'lon{n}_norm_tmp'], axis=1) - - if (n == 1) | (n == 4): - viajes_matrices = viajes_matrices.merge(zonificaciones[['zona', 'id', 'lat', 'lon']].rename(columns={'id': f'{i}', 'lat': f'lat{n}_tmp', 'lon': f'lon{n}_tmp'}), - how='left', - on=['zona', f'{i}']) - viajes_matrices.loc[viajes_matrices[f'{poly_lst[n-1]}'] == '', - f'lat{n}'] = viajes_matrices.loc[viajes_matrices[f'{poly_lst[n-1]}'] == '', f'lat{n}_tmp'] - viajes_matrices.loc[viajes_matrices[f'{poly_lst[n-1]}'] == '', - f'lon{n}'] = viajes_matrices.loc[viajes_matrices[f'{poly_lst[n-1]}'] == '', f'lon{n}_tmp'] - viajes_matrices = viajes_matrices.drop( - [f'lat{n}_tmp', f'lon{n}_tmp'], axis=1) - - n += 1 - - - - # # Agrupar a nivel de mes y corregir factor de expansión - sum_viajes = etapas_agrupadas_all.groupby(['dia', - 'mes', - 'tipo_dia', - 'zona'], as_index=False).factor_expansion_linea.sum().groupby(['mes', - 'tipo_dia', - 'zona'], as_index=False).factor_expansion_linea.mean().round() + etapas_agrupadas_zon['transferencia'] = 0 + etapas_agrupadas_zon.loc[(etapas_agrupadas_zon.transfer1_norm != '') | ( + etapas_agrupadas_zon.transfer2_norm != ''), 'transferencia'] = 1 - aggregate_cols = ['mes', - 'tipo_dia', - 'id_polygon', - 'poly_inicio_norm', - 'poly_transfer1_norm', - 'poly_transfer2_norm', - 'poly_fin_norm', - 'zona', - 'inicio_norm', - 'transfer1_norm', - 'transfer2_norm', - 'fin_norm', - 'transferencia', - 'modo_agregado', - 'rango_hora', - 'genero', - 'tarifa', - 'coincidencias', - 'distancia', ] - weighted_mean_cols=['distance_osm_drive', - 'distance_osm_drive_etapas', - 'travel_time_min', - 'travel_speed', - 'lat1_norm', - 'lon1_norm', - 'lat2_norm', - 'lon2_norm', - 'lat3_norm', - 'lon3_norm', - 'lat4_norm', - 'lon4_norm'] - - etapas_agrupadas_all = calculate_weighted_means(etapas_agrupadas_all, - aggregate_cols=aggregate_cols, - weighted_mean_cols=weighted_mean_cols, - weight_col='factor_expansion_linea', - zero_to_nan=zero_to_nan, - var_fex_summed=False) + etapas_agrupadas_zon = etapas_agrupadas_zon.merge( + distancias_all, how='left') + + etapas_agrupadas_zon['tipo_dia_'] = pd.to_datetime(etapas_agrupadas_zon.dia).dt.weekday.astype(str).copy() + etapas_agrupadas_zon['tipo_dia'] = 'Hábil' + etapas_agrupadas_zon.loc[etapas_agrupadas_zon.tipo_dia_.astype(int)>=5, 'tipo_dia'] = 'Fin de Semana' + etapas_agrupadas_zon = etapas_agrupadas_zon.drop(['tipo_dia_'], axis=1) + etapas_agrupadas_zon['mes'] = etapas_agrupadas_zon.dia.str[:7] + + etapas_agrupadas_zon = etapas_agrupadas_zon[['id_polygon', 'zona', 'dia', 'mes', 'tipo_dia', 'id_tarjeta', 'id_viaje', + 'h3_inicio', 'h3_transfer1', 'h3_transfer2', 'h3_fin', + 'inicio', 'transfer1', 'transfer2', 'fin', + 'poly_inicio', 'poly_transfer1', 'poly_transfer2', 'poly_fin', + 'inicio_norm', 'transfer1_norm', 'transfer2_norm', 'fin_norm', + 'poly_inicio_norm', 'poly_transfer1_norm', 'poly_transfer2_norm', 'poly_fin_norm', + 'lon1', 'lat1', 'lon2', 'lat2', 'lon3', 'lat3', 'lon4', 'lat4', + 'lon1_norm', 'lat1_norm', 'lon2_norm', 'lat2_norm', 'lon3_norm', 'lat3_norm', 'lon4_norm', 'lat4_norm', + 'transferencia', 'modo_agregado', 'rango_hora', 'genero', 'tarifa', 'coincidencias', 'distancia', + 'distance_osm_drive', 'distance_osm_drive_etapas', + 'travel_time_min', 'travel_speed', + 'factor_expansion_linea']] + + aggregate_cols = ['id_polygon', 'dia', 'mes', 'tipo_dia', 'zona', 'inicio', 'fin', 'poly_inicio', + 'poly_fin', 'transferencia', 'modo_agregado', 'rango_hora', 'genero', 'tarifa', 'coincidencias', 'distancia'] + viajes_matrices = construyo_matrices(etapas_agrupadas_zon, + aggregate_cols, + zonificaciones, + False, + False, + False) + + # Agrupación de viajes + aggregate_cols = ['id_polygon', + 'dia', + 'mes', + 'tipo_dia', + 'zona', + 'inicio_norm', + 'transfer1_norm', + 'transfer2_norm', + 'fin_norm', + 'poly_inicio_norm', + 'poly_transfer1_norm', + 'poly_transfer2_norm', + 'poly_fin_norm', + 'transferencia', + 'modo_agregado', + 'rango_hora', + 'genero', + 'tarifa', + 'coincidencias', + 'distancia'] + + weighted_mean_cols = ['distance_osm_drive', + 'distance_osm_drive_etapas', + 'travel_time_min', + 'travel_speed', + 'lat1_norm', + 'lon1_norm', + 'lat2_norm', + 'lon2_norm', + 'lat3_norm', + 'lon3_norm', + 'lat4_norm', + 'lon4_norm'] + + weight_col = 'factor_expansion_linea' + + zero_to_nan = ['lat1_norm', + 'lon1_norm', + 'lat2_norm', + 'lon2_norm', + 'lat3_norm', + 'lon3_norm', + 'lat4_norm', + 'lon4_norm'] + + etapas_agrupadas_zon = agrupar_viajes(etapas_agrupadas_zon, + aggregate_cols, + weighted_mean_cols, + weight_col, + zero_to_nan, + agg_transferencias=False, + agg_modo=False, + agg_hora=False, + agg_distancia=False) + + zonificaciones['lat'] = zonificaciones.geometry.representative_point().y + zonificaciones['lon'] = zonificaciones.geometry.representative_point().x + + n = 1 + poly_lst = ['poly_inicio', 'poly_transfer1', 'poly_transfer2', 'poly_fin'] + for i in ['inicio', 'transfer1', 'transfer2', 'fin']: + etapas_agrupadas_zon = etapas_agrupadas_zon.merge(zonificaciones[['zona', 'id', 'lat', 'lon']].rename(columns={'id': f'{i}_norm', 'lat': f'lat{n}_norm_tmp', 'lon': f'lon{n}_norm_tmp'}), + how='left', + on=['zona', f'{i}_norm']) + etapas_agrupadas_zon.loc[etapas_agrupadas_zon[f'{poly_lst[n-1]}_norm'] == '', + f'lat{n}_norm'] = etapas_agrupadas_zon.loc[etapas_agrupadas_zon[f'{poly_lst[n-1]}_norm'] == '', f'lat{n}_norm_tmp'] + etapas_agrupadas_zon.loc[etapas_agrupadas_zon[f'{poly_lst[n-1]}_norm'] == '', + f'lon{n}_norm'] = etapas_agrupadas_zon.loc[etapas_agrupadas_zon[f'{poly_lst[n-1]}_norm'] == '', f'lon{n}_norm_tmp'] + + etapas_agrupadas_zon = etapas_agrupadas_zon.drop( + [f'lat{n}_norm_tmp', f'lon{n}_norm_tmp'], axis=1) + + if (n == 1) | (n == 4): + viajes_matrices = viajes_matrices.merge(zonificaciones[['zona', 'id', 'lat', 'lon']].rename(columns={'id': f'{i}', 'lat': f'lat{n}_tmp', 'lon': f'lon{n}_tmp'}), + how='left', + on=['zona', f'{i}']) + viajes_matrices.loc[viajes_matrices[f'{poly_lst[n-1]}'] == '', + f'lat{n}'] = viajes_matrices.loc[viajes_matrices[f'{poly_lst[n-1]}'] == '', f'lat{n}_tmp'] + viajes_matrices.loc[viajes_matrices[f'{poly_lst[n-1]}'] == '', + f'lon{n}'] = viajes_matrices.loc[viajes_matrices[f'{poly_lst[n-1]}'] == '', f'lon{n}_tmp'] + viajes_matrices = viajes_matrices.drop( + [f'lat{n}_tmp', f'lon{n}_tmp'], axis=1) + + n += 1 + + + + # # Agrupar a nivel de mes y corregir factor de expansión + sum_viajes = etapas_agrupadas_zon.groupby(['dia', + 'mes', + 'tipo_dia', + 'zona'], as_index=False).factor_expansion_linea.sum().groupby(['mes', + 'tipo_dia', + 'zona'], as_index=False).factor_expansion_linea.mean().round() + + aggregate_cols = ['mes', + 'tipo_dia', + 'id_polygon', + 'poly_inicio_norm', + 'poly_transfer1_norm', + 'poly_transfer2_norm', + 'poly_fin_norm', + 'zona', + 'inicio_norm', + 'transfer1_norm', + 'transfer2_norm', + 'fin_norm', + 'transferencia', + 'modo_agregado', + 'rango_hora', + 'genero', + 'tarifa', + 'coincidencias', + 'distancia', ] + weighted_mean_cols=['distance_osm_drive', + 'distance_osm_drive_etapas', + 'travel_time_min', + 'travel_speed', + 'lat1_norm', + 'lon1_norm', + 'lat2_norm', + 'lon2_norm', + 'lat3_norm', + 'lon3_norm', + 'lat4_norm', + 'lon4_norm'] + + etapas_agrupadas_zon = calculate_weighted_means(etapas_agrupadas_zon, + aggregate_cols=aggregate_cols, + weighted_mean_cols=weighted_mean_cols, + weight_col='factor_expansion_linea', + zero_to_nan=zero_to_nan, + var_fex_summed=False) + + + sum_viajes['factor_expansion_linea'] = 1 - (sum_viajes['factor_expansion_linea'] / etapas_agrupadas_zon.groupby(['mes', 'tipo_dia', 'zona'], as_index=False).factor_expansion_linea.sum().factor_expansion_linea ) + sum_viajes = sum_viajes.rename(columns={'factor_expansion_linea':'factor_correccion'}) + + etapas_agrupadas_zon = etapas_agrupadas_zon.merge(sum_viajes) + etapas_agrupadas_zon['factor_expansion_linea2'] = etapas_agrupadas_zon['factor_expansion_linea'] * etapas_agrupadas_zon['factor_correccion'] + etapas_agrupadas_zon['factor_expansion_linea2'] = etapas_agrupadas_zon['factor_expansion_linea'] - etapas_agrupadas_zon['factor_expansion_linea2'] + etapas_agrupadas_zon = etapas_agrupadas_zon.drop(['factor_correccion', 'factor_expansion_linea'], axis=1) + etapas_agrupadas_zon = etapas_agrupadas_zon.rename(columns={'factor_expansion_linea2':'factor_expansion_linea'}) + + # # Agrupar a nivel de mes y corregir factor de expansión + sum_viajes = viajes_matrices.groupby(['dia', 'mes', 'tipo_dia', 'zona'], as_index=False).factor_expansion_linea.sum().groupby(['mes', 'tipo_dia', 'zona'], as_index=False).factor_expansion_linea.mean() + + aggregate_cols = ['id_polygon', + 'poly_inicio', + 'poly_fin', + 'mes', + 'tipo_dia', + 'zona', + 'inicio', + 'fin', + 'transferencia', + 'modo_agregado', + 'rango_hora', + 'genero', + 'tarifa', + 'coincidencias', + 'distancia', + 'orden_origen', + 'orden_destino', + 'Origen', + 'Destino'] + weighted_mean_cols = ['lat1', + 'lon1', + 'lat4', + 'lon4', + 'distance_osm_drive', + 'travel_time_min', + 'travel_speed',] + zero_to_nan = ['lat1', + 'lon1', + 'lat4', + 'lon4'] + + viajes_matrices = calculate_weighted_means(viajes_matrices, + aggregate_cols=aggregate_cols, + weighted_mean_cols=weighted_mean_cols, + weight_col='factor_expansion_linea', + zero_to_nan=zero_to_nan, + var_fex_summed=False) + + sum_viajes['factor_expansion_linea'] = 1 - (sum_viajes['factor_expansion_linea'] / viajes_matrices.groupby(['mes', 'tipo_dia', 'zona'], as_index=False).factor_expansion_linea.sum().factor_expansion_linea ) + sum_viajes = sum_viajes.rename(columns={'factor_expansion_linea':'factor_correccion'}) + + viajes_matrices = viajes_matrices.merge(sum_viajes) + viajes_matrices['factor_expansion_linea2'] = viajes_matrices['factor_expansion_linea'] * viajes_matrices['factor_correccion'] + viajes_matrices['factor_expansion_linea2'] = viajes_matrices['factor_expansion_linea'] - viajes_matrices['factor_expansion_linea2'] + viajes_matrices = viajes_matrices.drop(['factor_correccion', 'factor_expansion_linea'], axis=1) + viajes_matrices = viajes_matrices.rename(columns={'factor_expansion_linea2':'factor_expansion_linea'}) + + if len(poligonos[poligonos.tipo=='cuenca'])>0: + + etapas_agrupadas_zon.loc[ + etapas_agrupadas_zon.poly_inicio_norm.isin( + poligonos[poligonos.tipo=='cuenca'].id.unique()), + 'inicio_norm'] = etapas_agrupadas_zon.loc[ + etapas_agrupadas_zon.poly_inicio_norm.isin( + poligonos[poligonos.tipo=='cuenca'].id.unique()), 'inicio_norm']+' (cuenca)' + etapas_agrupadas_zon.loc[ + etapas_agrupadas_zon.poly_transfer1_norm.isin( + poligonos[poligonos.tipo=='cuenca'].id.unique()), + 'transfer1_norm'] = etapas_agrupadas_zon.loc[ + etapas_agrupadas_zon.poly_transfer1_norm.isin(poligonos[poligonos.tipo=='cuenca'].id.unique()), 'transfer1_norm']+' (cuenca)' + etapas_agrupadas_zon.loc[ + etapas_agrupadas_zon.poly_transfer2_norm.isin( + poligonos[poligonos.tipo=='cuenca'].id.unique()), + 'transfer2_norm'] = etapas_agrupadas_zon.loc[etapas_agrupadas_zon.poly_transfer2_norm.isin(poligonos[poligonos.tipo=='cuenca'].id.unique()), 'transfer2_norm']+' (cuenca)' + etapas_agrupadas_zon.loc[ + etapas_agrupadas_zon.poly_fin_norm.isin( + poligonos[poligonos.tipo=='cuenca'].id.unique()), + 'fin_norm'] = etapas_agrupadas_zon.loc[etapas_agrupadas_zon.poly_fin_norm.isin(poligonos[poligonos.tipo=='cuenca'].id.unique()), 'fin_norm']+' (cuenca)' + viajes_matrices.loc[ + viajes_matrices.poly_inicio.isin( + poligonos[poligonos.tipo=='cuenca'].id.unique()), + 'Origen'] = viajes_matrices.loc[viajes_matrices.poly_inicio.isin(poligonos[poligonos.tipo=='cuenca'].id.unique()), 'Origen']+' (cuenca)' + viajes_matrices.loc[ + viajes_matrices.poly_fin.isin( + poligonos[poligonos.tipo=='cuenca'].id.unique()), + 'Destino'] = viajes_matrices.loc[viajes_matrices.poly_fin.isin(poligonos[poligonos.tipo=='cuenca'].id.unique()), 'Destino']+' (cuenca)' + viajes_matrices.loc[ + viajes_matrices.poly_inicio.isin( + poligonos[poligonos.tipo=='cuenca'].id.unique()), + 'inicio'] = viajes_matrices.loc[viajes_matrices.poly_inicio.isin(poligonos[poligonos.tipo=='cuenca'].id.unique()), 'inicio']+' (cuenca)' + viajes_matrices.loc[ + viajes_matrices.poly_fin.isin( + poligonos[poligonos.tipo== + 'cuenca'].id.unique()), 'fin'] = viajes_matrices.loc[viajes_matrices.poly_fin.isin(poligonos[poligonos.tipo=='cuenca'].id.unique()), 'fin']+' (cuenca)' + + etapas_agrupadas_zon = etapas_agrupadas_zon.fillna(0) - sum_viajes['factor_expansion_linea'] = 1 - (sum_viajes['factor_expansion_linea'] / etapas_agrupadas_all.groupby(['mes', 'tipo_dia', 'zona'], as_index=False).factor_expansion_linea.sum().factor_expansion_linea ) - sum_viajes = sum_viajes.rename(columns={'factor_expansion_linea':'factor_correccion'}) - - etapas_agrupadas_all = etapas_agrupadas_all.merge(sum_viajes) - etapas_agrupadas_all['factor_expansion_linea2'] = etapas_agrupadas_all['factor_expansion_linea'] * etapas_agrupadas_all['factor_correccion'] - etapas_agrupadas_all['factor_expansion_linea2'] = etapas_agrupadas_all['factor_expansion_linea'] - etapas_agrupadas_all['factor_expansion_linea2'] - etapas_agrupadas_all = etapas_agrupadas_all.drop(['factor_correccion', 'factor_expansion_linea'], axis=1) - etapas_agrupadas_all = etapas_agrupadas_all.rename(columns={'factor_expansion_linea2':'factor_expansion_linea'}) - - # # Agrupar a nivel de mes y corregir factor de expansión - sum_viajes = viajes_matrices.groupby(['dia', 'mes', 'tipo_dia', 'zona'], as_index=False).factor_expansion_linea.sum().groupby(['mes', 'tipo_dia', 'zona'], as_index=False).factor_expansion_linea.mean() - - aggregate_cols = ['id_polygon', - 'poly_inicio', - 'poly_fin', - 'mes', - 'tipo_dia', - 'zona', - 'inicio', - 'fin', - 'transferencia', - 'modo_agregado', - 'rango_hora', - 'genero', - 'tarifa', - 'coincidencias', - 'distancia', - 'orden_origen', - 'orden_destino', - 'Origen', - 'Destino'] - weighted_mean_cols = ['lat1', - 'lon1', - 'lat4', - 'lon4', - 'distance_osm_drive', - 'travel_time_min', - 'travel_speed',] - zero_to_nan = ['lat1', - 'lon1', - 'lat4', - 'lon4'] - - viajes_matrices = calculate_weighted_means(viajes_matrices, - aggregate_cols=aggregate_cols, - weighted_mean_cols=weighted_mean_cols, - weight_col='factor_expansion_linea', - zero_to_nan=zero_to_nan, - var_fex_summed=False) - - sum_viajes['factor_expansion_linea'] = 1 - (sum_viajes['factor_expansion_linea'] / viajes_matrices.groupby(['mes', 'tipo_dia', 'zona'], as_index=False).factor_expansion_linea.sum().factor_expansion_linea ) - sum_viajes = sum_viajes.rename(columns={'factor_expansion_linea':'factor_correccion'}) - - viajes_matrices = viajes_matrices.merge(sum_viajes) - viajes_matrices['factor_expansion_linea2'] = viajes_matrices['factor_expansion_linea'] * viajes_matrices['factor_correccion'] - viajes_matrices['factor_expansion_linea2'] = viajes_matrices['factor_expansion_linea'] - viajes_matrices['factor_expansion_linea2'] - viajes_matrices = viajes_matrices.drop(['factor_correccion', 'factor_expansion_linea'], axis=1) - viajes_matrices = viajes_matrices.rename(columns={'factor_expansion_linea2':'factor_expansion_linea'}) - - if id_polygon == 'NONE': - etapas_agrupadas_all = etapas_agrupadas_all.drop(['id_polygon', - 'poly_inicio_norm', - 'poly_transfer1_norm', - 'poly_transfer2_norm', - 'poly_fin_norm'], axis=1) - - viajes_matrices = viajes_matrices.drop( - ['poly_inicio', - 'poly_fin'], axis=1) + if id_polygon == 'NONE': + + etapas_agrupadas_zon = etapas_agrupadas_zon.drop(['id_polygon', + 'poly_inicio_norm', + 'poly_transfer1_norm', + 'poly_transfer2_norm', + 'poly_fin_norm'], axis=1) - if len(poligonos[poligonos.tipo=='cuenca'])>0: - - etapas_agrupadas_all.loc[etapas_agrupadas_all.poly_inicio_norm.isin(poligonos[poligonos.tipo=='cuenca'].id.unique()), 'inicio_norm'] = etapas_agrupadas_all.loc[etapas_agrupadas_all.poly_inicio_norm.isin(poligonos[poligonos.tipo=='cuenca'].id.unique()), 'inicio_norm']+' (cuenca)' - etapas_agrupadas_all.loc[etapas_agrupadas_all.poly_transfer1_norm.isin(poligonos[poligonos.tipo=='cuenca'].id.unique()), 'transfer1_norm'] = etapas_agrupadas_all.loc[etapas_agrupadas_all.poly_transfer1_norm.isin(poligonos[poligonos.tipo=='cuenca'].id.unique()), 'transfer1_norm']+' (cuenca)' - etapas_agrupadas_all.loc[etapas_agrupadas_all.poly_transfer2_norm.isin(poligonos[poligonos.tipo=='cuenca'].id.unique()), 'transfer2_norm'] = etapas_agrupadas_all.loc[etapas_agrupadas_all.poly_transfer2_norm.isin(poligonos[poligonos.tipo=='cuenca'].id.unique()), 'transfer2_norm']+' (cuenca)' - etapas_agrupadas_all.loc[etapas_agrupadas_all.poly_fin_norm.isin(poligonos[poligonos.tipo=='cuenca'].id.unique()), 'fin_norm'] = etapas_agrupadas_all.loc[etapas_agrupadas_all.poly_fin_norm.isin(poligonos[poligonos.tipo=='cuenca'].id.unique()), 'fin_norm']+' (cuenca)' - viajes_matrices.loc[viajes_matrices.poly_inicio.isin(poligonos[poligonos.tipo=='cuenca'].id.unique()), 'Origen'] = viajes_matrices.loc[viajes_matrices.poly_inicio.isin(poligonos[poligonos.tipo=='cuenca'].id.unique()), 'Origen']+' (cuenca)' - viajes_matrices.loc[viajes_matrices.poly_fin.isin(poligonos[poligonos.tipo=='cuenca'].id.unique()), 'Destino'] = viajes_matrices.loc[viajes_matrices.poly_fin.isin(poligonos[poligonos.tipo=='cuenca'].id.unique()), 'Destino']+' (cuenca)' - viajes_matrices.loc[viajes_matrices.poly_inicio.isin(poligonos[poligonos.tipo=='cuenca'].id.unique()), 'inicio'] = viajes_matrices.loc[viajes_matrices.poly_inicio.isin(poligonos[poligonos.tipo=='cuenca'].id.unique()), 'inicio']+' (cuenca)' - viajes_matrices.loc[viajes_matrices.poly_fin.isin(poligonos[poligonos.tipo=='cuenca'].id.unique()), 'fin'] = viajes_matrices.loc[viajes_matrices.poly_fin.isin(poligonos[poligonos.tipo=='cuenca'].id.unique()), 'fin']+' (cuenca)' - - return etapas_agrupadas_all, etapas_sin_agrupar, viajes_matrices, zonificaciones + viajes_matrices = viajes_matrices.drop( + ['poly_inicio', + 'poly_fin'], axis=1) + + guardar_tabla_sql(etapas_agrupadas_zon, + 'agg_etapas', + 'dash', + {'mes': etapas_agrupadas_zon.mes.unique().tolist(), + 'zona': etapas_agrupadas_zon.zona.unique().tolist()}) + + guardar_tabla_sql(viajes_matrices, + 'agg_matrices', + 'dash', + {'mes': viajes_matrices.mes.unique().tolist(), + 'zona': viajes_matrices.zona.unique().tolist()}) + else: + guardar_tabla_sql(etapas_agrupadas_zon, + 'poly_etapas', + 'dash', + {'mes': etapas_agrupadas_zon.mes.unique().tolist(), + 'zona': etapas_agrupadas_zon.zona.unique().tolist(), + 'id_polygon': etapas_agrupadas_zon.id_polygon.unique().tolist()}) + + guardar_tabla_sql(viajes_matrices, + 'poly_matrices', + 'dash', + {'mes': viajes_matrices.mes.unique().tolist(), + 'zona': viajes_matrices.zona.unique().tolist(), + 'id_polygon': viajes_matrices.id_polygon.unique().tolist()}) + + +### return etapas_agrupadas_zon, viajes_matrices, zonificaciones def proceso_poligonos(check_configs=True): @@ -1420,22 +1486,20 @@ def proceso_poligonos(check_configs=True): etapas_selec, viajes_selec, polygons, polygons_h3 = select_cases_from_polygons( etapas[etapas.od_validado == 1], viajes[viajes.od_validado == 1], poligonos, res=res) - etapas_agrupadas, etapas_sin_agrupar, viajes_matrices, zonificaciones = preparo_lineas_deseo( - etapas_selec, viajes_selec, polygons_h3, poligonos=poligonos, res=[6]) + preparo_lineas_deseo(etapas_selec, viajes_selec, polygons_h3, poligonos=poligonos, res=[6]) indicadores = construyo_indicadores(viajes_selec, poligonos=True) - etapas_agrupadas = etapas_agrupadas.fillna(0) - guardar_tabla_sql(etapas_agrupadas, - 'poly_etapas', - 'dash', - {'mes': etapas_agrupadas.mes.unique().tolist()}) + ## guardar_tabla_sql(etapas_agrupadas, + ## 'poly_etapas', + ## 'dash', + ## {'mes': etapas_agrupadas.mes.unique().tolist()}) - guardar_tabla_sql(viajes_matrices, - 'poly_matrices', - 'dash', - {'mes': viajes_matrices.mes.unique().tolist()}) + ## guardar_tabla_sql(viajes_matrices, + ## 'poly_matrices', + ## 'dash', + ## {'mes': viajes_matrices.mes.unique().tolist()}) guardar_tabla_sql(indicadores, 'poly_indicadores', @@ -1457,8 +1521,7 @@ def proceso_lineas_deseo(check_configs=False): etapas, viajes = load_and_process_data() - etapas_agrupadas, etapas_sin_agrupar, viajes_matrices, zonificaciones = preparo_lineas_deseo( - etapas, viajes, res=[6]) + preparo_lineas_deseo(etapas, viajes, res=[6]) indicadores = construyo_indicadores(viajes, poligonos=False) @@ -1466,16 +1529,16 @@ def proceso_lineas_deseo(check_configs=False): print('Guardo datos para dashboard') - etapas_agrupadas = etapas_agrupadas.fillna(0) - guardar_tabla_sql(etapas_agrupadas, - 'agg_etapas', - 'dash', - {'mes': etapas_agrupadas.mes.unique().tolist()}) + ## guardar_tabla_sql(etapas_agrupadas, + ## 'agg_etapas', + ## 'dash', + ## {'mes': etapas_agrupadas.mes.unique().tolist()}) + + ## guardar_tabla_sql(viajes_matrices, + ## 'agg_matrices', + ## 'dash', + ## {'mes': viajes_matrices.mes.unique().tolist()}) - guardar_tabla_sql(viajes_matrices, - 'agg_matrices', - 'dash', - {'mes': viajes_matrices.mes.unique().tolist()}) guardar_tabla_sql(indicadores, 'agg_indicadores', 'dash', @@ -1486,7 +1549,7 @@ def proceso_lineas_deseo(check_configs=False): 'dash', {'mes': socio_indicadores.mes.unique().tolist()}) - e_agg, v_agg = preparo_etapas_agregadas(etapas, viajes) + e_agg, v_agg, transfers = preparo_etapas_agregadas(etapas, viajes) guardar_tabla_sql(e_agg, 'etapas_agregadas', 'dash', @@ -1497,4 +1560,9 @@ def proceso_lineas_deseo(check_configs=False): 'dash', {'mes': v_agg.mes.unique().tolist()}) + guardar_tabla_sql(transfers, + 'transferencias_agregadas', + 'dash', + {'mes': v_agg.mes.unique().tolist()}) + imprimo_matrices_od()