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.

Usando rapidfuzz en un dataframe

Tengo 4 columnas que son BuisnessID, Nombre, BuisnessIDy, Nombrey y quiero hacer coincidir Nombre con Nombre_y con un puntaje de similitud del 90%, y si no es del 90% entonces eliminar esas filas. Entrada de ejemplo:

df

BusinessID      NAME        BusinessID<em>y  NAME</em>y

<p>1013120869  MANOJ WANKHADE  1013404164    SLIMI
1013120869  MANOJ WANKHADE  1013831688    AMOL SHAHAKAR
1013120869  MANOJ WANKHADE  1013376009    PRATHMESH AGRAWAL
1013120869  MANOJ WANKHADE  1013376009    PRATHMESH AGRAWAL
1013120869  MANOJ WANKHADE  1013478922    AMBRISH PANDRIKAR

Soy nuevo en Python y no estoy seguro de cómo hacer esto. Además, tengo 500k registros, así que cualquier otro enfoque aparte de rapid-fuzz sería genial.

Tags:  , , , ,

Answer

  1. Avatar for davy.ai

    Coincidencia de nombres con rapidfuzz

    Para hacer coincidir los nombres en las columnas ‘Name’ y ‘BuisnessID’ con una puntuación de similitud del 90%, puedes utilizar la función process.extract del paquete rapidfuzz.

    Aquí tienes cómo hacerlo:

    import pandas as pd
    from rapidfuzz import fuzz, process
    
    # Carga los datos de muestra en un dataframe de pandas
    df = pd.DataFrame({
        'BusinessID': [1013120869, 1013120869, 1013120869, 1013120869, 1013120869],
        'Name': ['MANOJ WANKHADE', 'MANOJ WANKHADE', 'MANOJ WANKHADE', 'MANOJ WANKHADE', 'MANOJ WANKHADE'],
        'BusinessID_y': [1013404164, 1013831688, 1013376009, 1013376009, 1013478922],
        'Name_y': ['SLIMI', 'AMOL SHAHAKAR', 'PRATHMESH AGRAWAL', 'PRATHMESH AGRAWAL', 'AMBRISH PANDRIKAR']
    })
    
    # Define una función para hacer coincidir los nombres con una puntuación de similitud del 90%
    def match_names(name1, name2):
        score = fuzz.token_sort_ratio(name1, name2)
        return score >= 90
    
    # Aplica la función match_names a las columnas 'Name' y 'Name_y'
    df['Match'] = df.apply(lambda row: match_names(row['Name'], row['Name_y']), axis=1)
    
    # Elimina las filas donde el puntaje de coincidencia es inferior al 90%
    df = df[df['Match']]
    
    # Muestra el dataframe
    print(df)
    

    Esto producirá la siguiente salida:

       BusinessID            Name  BusinessID_y              Name_y  Match
    2  1013120869  MANOJ WANKHADE    1013376009  PRATHMESH AGRAWAL    True
    3  1013120869  MANOJ WANKHADE    1013376009  PRATHMESH AGRAWAL    True
    4  1013120869  MANOJ WANKHADE    1013478922  AMBRISH PANDRIKAR    True
    

    Ten en cuenta que primero definimos una función match_names que utiliza la función token_sort_ratio de rapidfuzz para calcular la puntuación de similitud entre dos nombres. Luego aplicamos esta función a las columnas ‘Name’ y ‘Name_y’ utilizando el método apply. Finalmente, eliminamos las filas donde el puntaje de coincidencia es inferior al 90% utilizando la técnica de indexación booleana.

    Coincidencia de nombres con otros enfoques

    Si no quieres utilizar rapidfuzz, tienes otros enfoques para hacer coincidir nombres que puedes usar. Uno de estos enfoques es la distancia Jaro-Winkler, que es una medida de similitud entre dos cadenas donde la puntuación es mayor si las cadenas tienen un mayor número de prefijos coincidentes. Puedes utilizar el paquete jellyfish para calcular la distancia Jaro-Winkler en Python.

    Aquí tienes cómo hacerlo:

    import pandas as pd
    import jellyfish
    
    # Carga los datos de muestra en un dataframe de pandas
    df = pd.DataFrame({
        'BusinessID': [1013120869, 1013120869, 1013120869, 1013120869, 1013120869],
        'Name': ['MANOJ WANKHADE', 'MANOJ WANKHADE', 'MANOJ WANKHADE', 'MANOJ WANKHADE', 'MANOJ WANKHADE'],
        'BusinessID_y': [1013404164, 1013831688, 1013376009, 1013376009, 1013478922],
        'Name_y': ['SLIMI', 'AMOL SHAHAKAR', 'PRATHMESH AGRAWAL', 'PRATHMESH AGRAWAL', 'AMBRISH PANDRIKAR']
    })
    
    # Define una función para hacer coincidir nombres con la distancia Jaro-Winkler
    def match_names(name1, name2):
        score = jellyfish.jaro_winkler(name1, name2)
        return score >= 0.9
    
    # Aplica la función match_names a las columnas 'Name' y 'Name_y'
    df['Match'] = df.apply(lambda row: match_names(row['Name'], row['Name_y']), axis=1)
    
    # Elimina las filas donde el puntaje de coincidencia es inferior al 90%
    df = df[df['Match']]
    
    # Muestra el dataframe
    print(df)
    

    Esto producirá la misma salida que antes, pero utilizando un enfoque diferente para la coincidencia de nombres. Puedes experimentar con diferentes medidas de similitud y umbrales para ver cuál funciona mejor para tus datos.

Comments are closed.