Python regex para análisis de archivos CSV

Clase 25 de 29Curso de Expresiones Regulares

Resumen

Python y las expresiones regulares ofrecen una combinación potente para extraer datos de archivos CSV con precisión y velocidad. Con un patrón bien pensado, es posible filtrar partidos, capturar fechas, países y marcadores, y hasta sumar goles sin transformar previamente el archivo en estructuras complejas. Aquí verás cómo se arma el flujo completo, desde el shebang hasta la precompilación del patrón y el manejo de grupos.

¿Por qué Python y expresiones regulares aceleran el análisis de datos?

Python es un lenguaje rápido, potente y amigable para scripts de análisis de datos. Su módulo re permite compilar un patrón y reutilizarlo, lo que mejora el rendimiento en archivos grandes. Además, su sintaxis clara facilita centrarse en el patrón y no en el “pegamento” del código.

  • Shebang y ejecución directa: usar la primera línea con #! indica el binario, por ejemplo en /usr/bin/python, y permite ejecutar con permisos sin invocar el intérprete manualmente.
  • Sintaxis de patrones limpia: usar cadenas crudas con r'' evita escapar innecesario y mantiene el patrón legible.
  • Precompilación con re.compile: el patrón queda listo en memoria para hacer match repetidamente de forma eficiente.
  • Uso en back end: en servidores web como Apache o NGINX, las expresiones regulares ayudan a mapear rutas a queries GET (ejemplo: rutas tipo flickr.com/photos/usuario/id), reduciendo capas intermedias y acelerando el flujo.

¿Cómo implementar el patrón en Python paso a paso?

El flujo va de menos a más: leer, compilar, hacer match, capturar grupos y filtrar por criterios como friendly.

¿Cómo leer el archivo CSV con seguridad?

  • Abrir el archivo en modo lectura.
  • Iterar línea a línea.
  • Cerrar el archivo al finalizar.
#!/usr/bin/python
import re

f = open('files/results.csv', 'r')
for line in f:
    print(line)
f.close()
  • Si ves “dobles líneas” al imprimir, suele ser por el salto de línea incluido en cada línea más el de print.

¿Cómo compilar y agrupar con re.compile?

  • Emplear cadenas crudas r'' para los patrones.
  • Anclas ^ y $ para controlar el inicio y fin de línea.
  • Agrupar con paréntesis para extraer datos concretos (por ejemplo, el año).
pat = re.compile(r'^(\d{4})-.*$')  # grupo 1: año

f = open('files/results.csv', 'r')
for line in f:
    res = pat.match(line)
    if res:
        print(res.group(1))  # imprime el año
f.close()
  • Evitar \w para nombres de países con caracteres especiales. Conviene capturar “todo hasta la coma” con [^,]+.

¿Cómo filtrar por friendly y extraer grupos?

  • Para traer solo partidos amistosos, se puede buscar la secuencia ,friendly, en la línea.
  • Capturar fecha, local, visitante y marcador en un solo match.
pat = re.compile(
    r'^(\d{4}-\d{2}-\d{2}),([^,]+),([^,]+),(\d+)-(\d+),.*?,friendly,.*$'
)

f = open('files/results.csv', 'r')
for line in f:
    res = pat.match(line)
    if res:
        fecha   = res.group(1)
        local   = res.group(2)
        visita  = res.group(3)
        g_local = res.group(4)
        g_vis   = res.group(5)
        print(fecha, local, visita, g_local, g_vis)
f.close()
  • Este filtro asume que friendly aparece como un campo entre comas. Si friendly pudiera aparecer dentro del nombre de un país, habría falsos positivos; por eso se acota con comas.

¿Cómo operar con grupos y detectar partidos con muchos goles?

Una vez capturado el marcador, hacer cast a entero habilita operaciones numéricas como sumas y comparaciones por umbrales.

  • Patrón general (sin friendly) para leer fecha, equipos y goles.
pat = re.compile(r'^(\d{4}-\d{2}-\d{2}),([^,]+),([^,]+),(\d+)-(\d+),.*$')

f = open('files/results.csv', 'r')
for line in f:
    res = pat.match(line)
    if not res:
        continue
    fecha   = res.group(1)
    local   = res.group(2)
    visita  = res.group(3)
    g_local = int(res.group(4))
    g_vis   = int(res.group(5))

    total = g_local + g_vis
    if total > 10:
        print("%d goles: %s vs %s en %s" % (total, local, visita, fecha))
f.close()
  • Cast: convertir con int() desde strings permite sumar y comparar.
  • Formateo: con “%d” y “%s” se arma una salida tipo printf, clara y directa.

Resultados ilustrativos mencionados: - Se detectaron “festivales” de goles con umbrales > 10; se contó un total de 206 partidos oficiales por encima de ese valor. - Destaca un 31-0 en Australia vs American Samoa, un caso extremo de goleada. - También se estimaron 13209 partidos “menores que uno” (cero goles), es decir, 0-0.

Buenas prácticas derivadas del flujo: - Precompilar el patrón con re.compile para reutilizarlo sin degradar el rendimiento en archivos grandes. - Anclar y agrupar inteligentemente: ^ y $ para límites; grupos para año, fecha, equipos y goles. - Evitar \w en nombres con tildes o caracteres especiales; usar [^,]+ entre comas. - Cerrar archivos y probar incrementando complejidad: primero leer todo, luego agregar el patrón, después añadir filtros y operaciones.

¿Te gustaría explorar otros filtros, como diferenciar oficiales de amistosos, o imprimir marcadores locales y visitantes por separado? Comparte tu idea y la resolvemos juntos con un patrón claro y eficiente.