es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

Fusionando dos Dataframes de Pandas utilizando Expresiones Regulares

Soy nuevo en Python y Pandas, pero intento usar los Dataframes de Pandas para combinar dos dataframes basados en una expresión regular.

Tengo un dataframe con alrededor de 2 millones de filas. Esta tabla contiene datos sobre automóviles, pero el nombre del modelo a menudo se especifica de una manera creativa, por ejemplo, ‘Audi A100’, ‘Audi 100’, ‘Audit 100 Quadro’ o simplemente ‘A 100’. Y lo mismo ocurre con otras marcas. Esto se almacena en una columna llamada “Modelo”. En un segundo dataframe tengo el fabricante.

Índice Modelo Fabricante
0 A 100 Audi
1 A100 Quadro Audi
2 Audi A 100 Audi

Para limpiar los datos, creé alrededor de 1000 expresiones regulares para buscar algunas palabras clave y las almacené en un dataframe llamado ‘regex’. En una segunda columna de esta tabla, guardo el fabricante. Este valor se utiliza en un segundo paso para validar el resultado.

Índice RegEx Fabricante
0 .* A100 .* Audi
1 .* A 100 .* Audi
2 .* C240 .* Mercedes
3 .* ID3 .* Volkswagen

Espero que entiendas la idea.

Según tengo entendido, la función “merge()” de Pandas no funciona con expresiones regulares. Por lo tanto, uso un bucle para procesar la lista de expresiones regulares, luego uso la función “match” para localizar filas coincidentes en el DataFrame “cars” y asignar la expresión regular utilizada con éxito y el fabricante sugerido.

Añadí dos columnas adicionales a la tabla de automóviles, ‘RegEx’ y ‘Fabricante’.

for index, row in regex.iterrows():
    cars.loc[cars['Modelo'].str.match(row['RegEx']),'RegEx'] = row['RegEx']
    cars.loc[cars['Modelo'].str.match(row['RegEx']),'Fabricante'] = row['Fabricante']

He aprendido que ‘iterrows’ no debe utilizarse por razones de rendimiento. Tarda 8 minutos en terminar el bucle, lo cual no está mal. Sin embargo, ¿hay una mejor manera de hacerlo?

Saludos cordiales,
Jiriki

Tags:  , , ,

Answer

  1. Avatar for davy.ai

    Estimado Jiriki,

    Gracias por tu pregunta. El enfoque que has tomado es una solución válida para tu problema, pero como mencionaste, puede que no sea el más eficiente. En lugar de usar un bucle con iterrows(), puedes utilizar las funciones de cadena vectorizadas de Pandas. Las funciones vectorizadas pueden realizar operaciones en matrices completas de datos sin necesidad de un bucle. Esto puede mejorar significativamente el rendimiento, especialmente para conjuntos de datos grandes como el tuyo.

    Aquí tienes un ejemplo de cómo puedes utilizar las funciones de cadena vectorizadas de Pandas para lograr el resultado deseado:

    1. Fusiona los dos dataframes en la columna “Manufacturer”:
    merged_df = pd.merge(cars, regex, on='Manufacturer')
    
    1. Utiliza la función vectorizada str.contains() para crear una máscara booleana para cada patrón de regex:
    pattern_masks = [merged_df['Model'].str.contains(pattern) for pattern in merged_df['RegEx']]
    
    1. Combina las máscaras booleanas utilizando la función reduce() de la biblioteca functools. Esto creará una máscara final que coincida con todos los patrones de regex:
    from functools import reduce
    
    final_mask = reduce(lambda a, b: a | b, pattern_masks)
    
    1. Utiliza la máscara booleana final para seleccionar las filas y asignar el patrón de regex y el fabricante:
    merged_df.loc[final_mask, 'RegEx'] = merged_df.loc[final_mask, 'RegEx']
    merged_df.loc[final_mask, 'Manufacturer'] = merged_df.loc[final_mask, 'Manufacturer']
    
    1. Por último, elimina cualquier fila duplicada:
    merged_df.drop_duplicates(inplace=True)
    

    Este enfoque debería ser mucho más rápido que usar iterrows(), ya que utiliza operaciones vectorizadas en lugar de un bucle. Espero que esto te ayude.

    Saludos cordiales,
    [Tu Nombre]

Comments are closed.