Carga de librerías necesarias para el análisis:
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
Lectura de los datos desde un archivo Excel que contiene dos hojas: una con información de instalaciones y otra con registros de usuarios.
# Cargar datos
instalaciones = pd.read_excel('D:/Documentos/Notas/Datos_usuarios/Datos_integrados.xlsx', sheet_name='informacion_instalacion')
registros = pd.read_excel('D:/Documentos/Notas/Datos_usuarios/Datos_integrados.xlsx', sheet_name='informacion_registro')
print("Vista previa - Información de instalación:")
print(instalaciones.head())
print("Vista previa - Información de registro:")
print(registros.head())
Limpieza y exploración inicial de datos
Verificación de valores nulos, duplicados y estadísticas descriptivas para ambas tablas.
print("Información sobre instalaciones:")
print(instalaciones.info())
print("-" * 30)
print(instalaciones.describe())
print("-" * 30)
print("Valores nulos en instalaciones:\n", instalaciones.isnull().sum())
print("-" * 30)
print("Registros duplicados en instalaciones:", instalaciones.duplicated().sum())
print("Información sobre registros:")
print(registros.info())
print("-" * 30)
print(registros.describe())
print("-" * 30)
print("Valores nulos en registros:\n", registros.isnull().sum())
print("-" * 30)
print("Registros duplicados en registros:", registros.duplicated().sum())
Filtrado por rango temporal
Se restringe el análisis al período comprendido entre el 20 y el 26 de abril de 2020 para mayor consistencia.
instalaciones = instalaciones[instalaciones['Tiempo_instalacion'] > '2020-04-19 23:59:59']
registros = registros[registros['Tiempo_instalacion'] > '2020-04-19 23:59:59']
print("Rango de fechas en instalaciones:", instalaciones['Tiempo_instalacion'].min(), "-", instalaciones['Tiempo_instalacion'].max())
print("Rango de fechas en registros:", registros['Tiempo_instalacion'].min(), "-", registros['Tiempo_instalacion'].max())
Relación entre instalaciones y registros
Se filtran los registros para incluir únicamente aquellos cuyo identificador único también figure en la tabla de instalaciones.
ids_instalados = instalaciones['ID_usuario'].unique()
registros = registros[registros['ID_usuario'].isin(ids_instalados)]
print("Tamaño después del filtro - Instalaciones:", instalaciones.shape)
print("Tamaño después del filtro - Registros:", registros.shape)
Eliminación de duplicados basándose en el identificador único del usuario.
print("Registros duplicados por ID_usuario:", registros['ID_usuario'].duplicated().sum())
registros = registros.drop_duplicates(subset='ID_usuario', keep='first')
print("Forma final de registros tras eliminar duplicados:", registros.shape)
Métricas clave
Cálculo del número total de instalaciones, registros y la tasa de activación (definida como proporción de usuarios registrados respecto a los que instalaron la app).
total_instalaciones = instalaciones.shape[0]
total_registros = registros.shape[0]
tasa_activacion = (total_registros / total_instalaciones) * 100
print(f"Total de instalaciones: {total_instalaciones}")
print(f"Total de registros: {total_registros}")
print(f"Tasa de activación: {tasa_activacion:.2f}%")
Desglose por atributos de instalación
Extracción de la fecha de instalación para análisis diarios.
instalaciones['Fecha_instalacion'] = instalaciones['Tiempo_instalacion'].dt.date
print("Instalaciones diarias:")
print(instalaciones.groupby('Fecha_instalacion')['ID_usuario'].count())
Distribución por canal, subcanal, región, uso de WiFi y versión del sistema operativo.
print("Canales de instalación:\n", instalaciones['Canal'].value_counts())
print("\nTop 15 subcanales:\n", instalaciones['Subcanal'].value_counts().head(15))
print("\nRegiones:\n", instalaciones['Region'].value_counts())
print("\n¿Conexión WiFi?:\n", instalaciones['WiFi'].value_counts())
print("\nVersiones del sistema operativo:\n", instalaciones['Sistema'].value_counts())
print("\nVersiones específicas del OS:\n", instalaciones.groupby('Version_OS')['Sistema'].count())
Normalización y clasificación del tipo de dispositivo móvil utilizado.
instalaciones['Tipo_dispositivo'] = instalaciones['Modelo'].str.split('-').str[0].str.title()
print("Top 15 tipos de dispositivos móviles:")
print(instalaciones['Tipo_dispositivo'].value_counts().head(15))
Análisis de comportamiento en el registro
Generación de métricas temporales relacionadas con el registro de usuarios.
registros['Fecha_registro'] = pd.to_datetime(registros['Tiempo_registro']).dt.date
print("Usuarios registrados por día:")
print(registros.groupby('Fecha_registro')['ID_usuario'].count())
Distribución por tipo de usuario (por ejemplo, nuevos o existentes).
print("Tipos de usuarios:\n", registros['Tipo_usuario'].value_counts().reset_index(name='Cantidad'))
Visualización del patrón horario de registros por tipo de usuario.
plt.rcParams['font.sans-serif'] = 'SimHei'
plt.rcParams['axes.unicode_minus'] = False
registros['Hora_registro'] = pd.to_datetime(registros['Tiempo_registro']).dt.hour
datos_hora = registros.groupby(['Tipo_usuario', 'Hora_registro'])['ID_usuario'].count().reset_index(name='total')
sns.lineplot(data=datos_hora, x='Hora_registro', y='total', hue='Tipo_usuario')
plt.title('Usuarios registrados por hora del día', loc='left')
plt.xlabel('Hora del día')
plt.ylabel('Número de registros')
plt.show()
Tiempo transcurrido entre la instalación y el registro (activación).
registros['Tiempo_activacion_dias'] = pd.to_datetime(registros['Tiempo_registro']).dt.day - pd.to_datetime(registros['Tiempo_instalacion']).dt.day
activacion = registros['Tiempo_activacion_dias'].value_counts().reset_index(name='total')
activacion['porcentaje'] = (activacion['total'] / total_registros).round(3)
print("Días hasta la activación:\n", activacion)
# Interpretación: 4655 usuarios se registraron el mismo día (63.9% del total instalado), mientras que cerca del 32.5% no completó el registro dentro de los primeros 7 días.
Nuevos usuarios agregados por día durante el período analizado.
nuevos_usuarios = registros[registros['Tipo_usuario'] == 'new']
print("Nuevos usuarios por fecha:")
print(nuevos_usuarios.groupby('Fecha_registro')['ID_usuario'].count())