python pandas fuzzy-search fuzzywuzzy

python - Aplique coincidencias difusas en una columna de marco de datos y guarde los resultados en una nueva columna



pandas fuzzy-search (1)

No podía decir lo que estabas haciendo. Así es como lo haría.

from fuzzywuzzy import fuzz from fuzzywuzzy import process

Crea una serie de tuplas para comparar:

compare = pd.MultiIndex.from_product([df1[''Company''], df2[''FDA Company'']]).to_series()

Cree una función especial para calcular métricas difusas y devolver una serie.

def metrics(tup): return pd.Series([fuzz.ratio(*tup), fuzz.token_sort_ratio(*tup)], [''ratio'', ''token''])

Aplicar metrics a la serie de compare

compare.apply(metrics)

Hay muchas maneras de hacer esta siguiente parte:

Obtenga coincidencias más cercanas a cada fila de df1

compare.apply(metrics).unstack().idxmax().unstack(0)

Obtenga coincidencias más cercanas a cada fila de df2

compare.apply(metrics).unstack(0).idxmax().unstack(0)

Tengo dos marcos de datos con cada uno que tiene un número diferente de filas. A continuación hay un par de filas de cada conjunto de datos.

df1 = Company City State ZIP FREDDIE LEES AMERICAN GOURMET SAUCE St. Louis MO 63101 CITYARCHRIVER 2015 FOUNDATION St. Louis MO 63102 GLAXOSMITHKLINE CONSUMER HEALTHCARE St. Louis MO 63102 LACKEY SHEET METAL St. Louis MO 63102

y

df2 = FDA Company FDA City FDA State FDA ZIP LACKEY SHEET METAL St. Louis MO 63102 PRIMUS STERILIZER COMPANY LLC Great Bend KS 67530 HELGET GAS PRODUCTS INC Omaha NE 68127 ORTHOQUEST LLC La Vista NE 68128

Los uní uno al lado del otro usando combined_data = pandas.concat([df1, df2], axis = 1) . Mi próximo objetivo es comparar cada cadena en df1[''Company''] con cada cadena en df2[''FDA Company''] utilizando varios comandos de coincidencia diferentes del módulo fuzzy wuzzy y devolver el valor de la mejor coincidencia y su nombre. Quiero almacenar eso en una nueva columna. Por ejemplo, si hice fuzz.ratio y fuzz.token_sort_ratio en LACKY SHEET METAL en df1[''Company''] a df2[''FDA Company''] , devolvería que la mejor coincidencia fue LACKY SHEET METAL con un puntaje de 100 y esto luego se guardaría en una nueva columna en combined data . Los resultados se verían así

combined_data = Company City State ZIP FDA Company FDA City FDA State FDA ZIP fuzzy.token_sort_ratio match fuzzy.ratio match FREDDIE LEES AMERICAN GOURMET SAUCE St. Louis MO 63101 LACKEY SHEET METAL St. Louis MO 63102 LACKEY SHEET METAL 100 LACKEY SHEET METAL 100 CITYARCHRIVER 2015 FOUNDATION St. Louis MO 63102 PRIMUS STERILIZER COMPANY LLC Great Bend KS 67530 GLAXOSMITHKLINE CONSUMER HEALTHCARE St. Louis MO 63102 HELGET GAS PRODUCTS INC Omaha NE 68127 LACKEY SHEET METAL St. Louis MO 63102 ORTHOQUEST LLC La Vista NE 68128

Intenté hacer

combined_data[''name_ratio''] = combined_data.apply(lambda x: fuzz.ratio(x[''Company''], x[''FDA Company'']), axis = 1)

Pero recibí un error porque las longitudes de las columnas son diferentes.

Estoy perplejo ¿Cómo puedo lograr esto?