Python Programming

Extracción eficiente de números de cadenas en Python

Spread the love

Extraer datos numéricos de cadenas de texto es una tarea común en la programación Python, particularmente en la limpieza de datos y el web scraping. Este artículo explora varios métodos eficientes y versátiles para lograr esto, atendiendo a diferentes escenarios y niveles de complejidad.

Tabla de Contenidos

Método 1: Aprovechando las Expresiones Regulares

Las expresiones regulares (regex) ofrecen un enfoque potente y flexible, especialmente para estructuras de cadenas complejas. El módulo re de Python facilita este proceso.


import re

def extract_numbers_regex(text):
  """Extrae números de una cadena usando expresiones regulares."""
  numbers = re.findall(r'-?d+(.d+)?', text)  # Coincide con enteros y decimales, incluyendo números negativos
  return [float(num) for num in numbers]

text = "Hay -12 manzanas y 3.14 naranjas, y también 12345."
numbers = extract_numbers_regex(text)
print(numbers)  # Salida: [-12.0, 3.14, 12345.0]

Esta regex mejorada r'-?d+(.d+)?' maneja números negativos y decimales eficazmente.

Método 2: Utilizando List Comprehension

List comprehension proporciona una solución concisa y Pythonica, ideal para escenarios más simples donde los números están claramente delimitados.


def extract_numbers_list_comprehension(text):
  """Extrae enteros de una cadena usando list comprehension."""
  return [int(c) for c in text if c.isdigit()]

text = "123abc456"
numbers = extract_numbers_list_comprehension(text)
print(numbers)  # Salida: [1, 2, 3, 4, 5, 6]

Este método es eficiente para extraer dígitos individuales, pero puede no ser adecuado para números de varios dígitos o números con puntos decimales.

Método 3: Combinando filter y isdigit()

Este enfoque funcional usa filter() y isdigit() para una solución clara y legible, adecuada para casos más simples.


def extract_numbers_filter(text):
  """Extrae enteros de una cadena usando filter e isdigit()."""
  numbers = list(filter(str.isdigit, text))
  return [int(num) for num in numbers]

text = "1a2b3c4d5"
numbers = extract_numbers_filter(text)
print(numbers) #Salida: [1, 2, 3, 4, 5]

Similar a list comprehension, este método extrae dígitos individuales y no maneja formatos de número más complejos.

Método 4: Expresiones Regulares Avanzadas para Patrones Complejos

Las expresiones regulares realmente brillan al manejar patrones intrincados, como números en notación científica o con separadores de miles.


import re

def extract_numbers_complex(text):
    """Extrae números (incluyendo notación científica) de una cadena usando regex."""
    numbers = re.findall(r'-?d+(?:,d{3})*(?:.d+)?(?:[eE][+-]?d+)?', text)
    return [float(num.replace(',', '')) for num in numbers]

text = "El precio es $1,234.56 y la cantidad es 1.23e-5. Otro precio es 100,000"
numbers = extract_numbers_complex(text)
print(numbers) # Salida: ['1234.56', '1.23e-5', '100000']

Esta regex maneja comas como separadores de miles y notación científica. El replace(',', '') elimina las comas antes de la conversión a float.

Gestionando Variaciones en los Formatos de Número

Para adaptarse a varios formatos, considere estos puntos:

  • Números negativos: Incluya -? al principio de su patrón regex (ej., r'-?d+').
  • Notación científica: Añada (?:[eE][+-]?d+)? para manejar exponentes (como se muestra en el Método 4).
  • Separadores de miles: Use (?:,d{3})* para coincidir con separadores de miles opcionales (como se muestra en el Método 4).
  • Símbolos monetarios: Preprocese su cadena para eliminar los símbolos monetarios antes de la extracción, o use una regex más compleja.

Conclusión

El método óptimo depende de la complejidad de sus cadenas de entrada y la precisión deseada. Para casos simples, list comprehension o filter podrían ser suficientes. Sin embargo, para la robustez y el manejo de diversos formatos de número, las expresiones regulares son invaluables.

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *