# manejo-de-datos-en-pandas
Manejo de datos en Pandas
Volver a la portada del cursoProyecto: Análisis completo de datos
Sección 6 · Proyecto Final
Proyecto final: análisis completo de los pedidos de PyShop
Durante el curso trabajaste con el CSV de pedidos 2025 que juntaron las sucursales de PyShop: lo exploraste, lo limpiaste, trataste sus faltantes, lo agrupaste y lo graficaste. Ahora llega un archivo nuevo, más grande, con los mismos defectos en otra proporción. Tu tarea es entregar un análisis completo y reproducible: limpieza validada, reporte de calidad, respuestas a cinco preguntas de negocio, gráficas y conclusiones. Se usan Python 3.11 o superior y pandas (el curso usa pandas 3); para las gráficas basta con .plot. El notebook proyecto-pedidos contiene una solución de referencia: consúltalo al terminar, no antes.
Contexto
La dirección de PyShop recibió un nuevo consolidado de pedidos y quiere saber dos cosas: si los datos son confiables y qué dicen sobre categorías, ciudades y productos. No le interesa el código, sino un reporte claro; pero el análisis debe poder repetirse con el archivo del próximo periodo sin cambiar nada.
Datos
Usa la función generar_csv_pedidos, que está en la primera celda de código de cualquier notebook del curso, con otros argumentos: 1500 pedidos y semilla 2026. Devuelve el texto de un CSV con las mismas diez columnas de siempre.
import io
import pandas as pd
texto = generar_csv_pedidos(n=1500, semilla=2026)
crudo = pd.read_csv(io.StringIO(texto))
print(crudo.shape) # (1526, 10)
Si tu shape no es (1526, 10), revisa los argumentos de la función. Todas las demás cifras debes obtenerlas tú.
Requisitos mínimos
- Reporte de calidad. Una función
reporte_calidad(df)que devuelva, al menos: filas, filas duplicadas, ciudades distintas, tipo del precio, nulos por columna y fechas que no se pueden convertir. Aplícala al crudo y al limpio, y muestra ambas en una tabla «antes / después». - Limpieza. Una función
limpiar(texto)que devuelva un DataFrame limpio: sin duplicados, cinco ciudades bien escritas, precio numérico, fecha comodatetime64, faltantes de cantidad y precio tratados con un criterio justificado, filas sin fecha válida descartadas y una columnatotal. Se recomienda escribirla como cadena de métodos conassign. - Validación. Una función
validar(df)conassertque compruebe, al menos, quepedido_ides único, que hay exactamente cinco ciudades sin nulos y que cantidad, precio, fecha y total no tienen nulos. - La calificación. Decide qué hacer con sus faltantes y explica por qué en una celda de texto.
- Cinco preguntas de negocio, sin contar los pedidos cancelados en el ingreso:
- P1. ¿Qué categoría genera más ingreso y qué porcentaje del total aporta cada una?
- P2. Por ciudad: pedidos, ingreso, ticket medio y calificación media (con
aggcon nombres). ¿Qué ciudad tiene el ticket medio más alto? - P3. Ingreso por categoría y ciudad con
pivot_table. - P4. Tasa de cancelación por ciudad, en porcentaje (aquí sí cuentan los cancelados).
- P5. Los tres productos con más unidades vendidas.
- Tres gráficas con
.plot: un ranking (barras ordenadas), una tendencia mensual (línea con el eje desde cero) y una tercera a tu elección. Cada una con título y unidades. - Conclusiones: entre cuatro y seis frases, cada una con una cifra, y al menos una sobre lo que los datos no muestran.
Pistas de implementación
Revisa las variantes de ciudad antes de escribir el diccionario:
base = crudo["ciudad"].str.strip().str.lower()
print(sorted(base.unique()))
Dentro de una cadena, usa lambda d: para que cada columna se calcule sobre el DataFrame ya sin duplicados:
limpio = crudo.drop_duplicates().assign(
fecha=lambda d: pd.to_datetime(
d["fecha"], errors="coerce"),
)
La tasa de cancelación es la media de una columna booleana:
cancelado = pedidos["estado"] == "cancelado"
tasa = cancelado.groupby(pedidos["ciudad"]).mean()
print((tasa * 100).round(1))
El generador de datos no modela estacionalidad ni diferencias reales entre ciudades: si una cifra sube o baja, descríbela, pero no le inventes una causa.
Extras opcionales
- Precios contra el catálogo. Crea un DataFrame con
PRODUCTOSy únelo a los pedidos conmerge(on="producto", validate="many_to_one"). Compara el precio del archivo (convertido a número, antes de rellenar) con el del catálogo e informa cuántos difieren. ¿Qué te dice el resultado sobre los 33 precios distintos del crudo? - Exportar a Excel. Con
pd.ExcelWriterguarda en un solo archivo una hoja con los pedidos limpios y otra por cada tabla de P2 y P3. Requierepip install openpyxl. - Memoria. Convierte
estadoyciudadacategoryy mide el ahorro conmemory_usage(deep=True, index=False). - Una sola figura. Reúne las tres gráficas en
plt.subplots(1, 3)conax=y guárdala consavefig.
Entregables
- Un notebook que corra de principio a fin sin errores: datos, reporte de calidad,
limpiar,validar, preguntas, gráficas y conclusiones. - El CSV limpio,
pedidos_limpios.csv, guardado conindex=False. - Las conclusiones en una celda de texto al final del notebook.
Rúbrica (100 puntos, más 10 de extras)
- Reporte de calidad (15 puntos): mide lo pedido, antes y después, en una tabla.
- Limpieza (25 puntos): función reutilizable, orden correcto de los pasos y criterios de relleno justificados.
- Validación (10 puntos): los
assertpedidos y al menos uno propio. - Preguntas de negocio (25 puntos): cinco respuestas correctas, sin cancelados en el ingreso y con la tasa calculada sobre todos los pedidos.
- Gráficas (10 puntos): tipo adecuado, ordenadas, con título y unidades.
- Conclusiones (15 puntos): cifras concretas, una limitación de los datos y ninguna causa inventada.