2017-02-27 3 views
0

J'ai df1 et df2. Je souhaite utiliser fuzzywuzzy pour aligner la colonne A dans df1 sur la colonne A dans df2 et renvoyer un ID dans la colonne B de df2 en fonction d'une certaine correspondance de ratio.Comment utiliser FuzzyWuzzy en Python pour nommer la correspondance entre deux trames de données?

Par exemple:

DF1 ressemble à ceci:


Nom

Sally vend Seashells


DF2 ressemble à ceci:


Nom | ID

Sally slls sshells | 28904


Ce que je suis en train de faire est de comparer tout dans la colonne A DF1 pour trouver une correspondance dans la colonne A DF2 et retourner l'ID de la colonne B en DF2.

Je voudrais être en mesure de définir les critères du rapport flou. Par exemple: Je veux seulement revenir à un ID si le ratio est supérieur à 50.

Mon code actuel:

import pandas as pd 
import numpy as np 
from fuzzywuzzy import fuzz 
from fuzzywuzzy import process 
df1=pd.read_csv('C:\\Users\\nkurdob\\Desktop\\Sheet1.csv') 
df2=pd.read_csv('C:\\Users\\nkurdob\\Desktop\\Sheet2.csv') 


for i in range(len(df1)): 
    em = df1['A'][i] 
    test = fuzz.partial_ratio(em, df2['A']) 
    if test > 50: 
     print df1['A'][i]==df2['B'] 

Répondre

0

Tout d'abord merci pour la question, je n'ai jamais utilisé fuzzywuzzy avant ...

Voici ma réponse à votre question.

Ici, j'essaie de faire correspondre la colonne name dans 2 blocs de données, et je ne montrerai que les résultats qui ont un score supérieur à 50.

Comme je concaténerais alors ces résultats (ou remplacerais une colonne) J'ajoute des valeurs vierges là où il n'y a aucune correspondance .... évidemment vous pouvez ou ne pas vouloir faire ceci.

import pandas as pd 
import numpy as np 
from fuzzywuzzy import fuzz 
from fuzzywuzzy import process 

d1={1:'Tim','2':'Ted',3:'Sally',4:'Dick',5:'Ethel'} 
d2={1:'Tam','2':'Tid',3:'Sally',4:'Dicky',5:'Aardvark'} 

df1=pd.DataFrame.from_dict(d1,orient='index') 
df2=pd.DataFrame.from_dict(d2,orient='index') 

df1.columns=['Name'] 
df2.columns=['Name'] 

def match(Col1,Col2): 
    overall=[] 
    for n in Col1: 
     result=[(fuzz.partial_ratio(n, n2),n2) 
       for n2 in Col2 if fuzz.partial_ratio(n, n2)>50 
       ] 
     if len(result): 
      result.sort()  
      print('result {}'.format(result)) 
      print("Best M={}".format(result[-1][1])) 
      overall.append(result[-1][1]) 
     else: 
      overall.append(" ") 
    return overall 

print(match(df1.Name,df2.Name)) 

Lorsque ceci est exécuté, vous devriez voir une sortie comme celle-ci. Je ne montre évidemment que les résultats intermédiaires, donc je peux démontrer que la clause de correspondance de valeur fonctionne. Je trierai ensuite la liste des tuples (tels qu'ils ont été stockés avec l'ordre score-puis-valeur), prendre le dernier (vous pouvez inverser le tri et prendre la valeur supérieure à vous), puis je prends le 2ème élément ([1]) du tuple.

Cela devrait fonctionner pour toutes les colonnes à 2 cordes, mais je n'ai pas testé cela.