2017-09-20 3 views
2

J'ai 2 fichiers .csv. L'un d'eux avec de nouvelles données a ~ 100 lignes et un autre est un livre de référence avec ~ 40k lignes.Comparer 2 fichiers .csv avec un peu de calcul très lent

Je veux comparer toutes les chaînes du premier fichier (un par un) à toutes chaînes de deuxième et de calculer la distance Levenshtein à la chaîne la plus similaire. Après cela, j'ai besoin de créer un troisième fichier avec les résultats. (Avec toutes les données du premier fichier, la distance max Levenshtein et la chaîne à partir du deuxième fichier)

Par exemple:

Un fichier (nouvelles données):

Spam

foo

fichier B (livre de référence):

Bar 1 0

spamm 2 1

Spann 3 0

Booo 1 0

Fooo 2 2

Bo 3 3

...

Qu'est-ce que j'ai besoin (fichier résultat), où n = distance Levenshtein:

Spam n spamm

Foo n Fooo

Pour l'instant mon code est:

def calculate_Leven(source, ref, result_file): 
    with open(source, 'r') as input1: 
     with open(ref, 'r') as input2: 
      with open(result_file, 'w') as csvoutput: 
       reader1 = csv.reader(input1) 
       reader2 = list(csv.reader(input2)) 
       writer = csv.writer(csvoutput) 
       result = [] 
       headers = next(reader1) 
       result.append(headers) 
       for row1 in reader1: 
        print "First row" 
        max = 0 
        while max < 1 
         for row2 in reader2: 
          a = distance(row1[0],row2[0]) 
          b = 1 - a/len(row1[0]) 
          if b > max: 
           max = b 
           SKU = row2[0] 
        row1.append(max) 
        row1.append(SKU) 
        result.append(row1) 
       writer.writerows(result) 

Où la distance est une fonction pour calculer la distance de Levensthein.

Ce code fonctionne mais est extrêmement lent. Y a-t-il une meilleure façon de structurer cela, ou une voie alternative plus efficace? J'ai environ 100 nouveaux fichiers par jour à vérifier par rapport au livre de référence, de sorte que la faible vitesse est un goulot d'étranglement.

+0

connexes: https: // stackoverflow.com/questions/4173579/implementation-levenshtein-distance-en-python –

+0

Je pense que le problème n'est pas dans l'algorythme de Levenshtein. Cela fonctionne bien et correct. J'ai vérifié sur de petites données par exemple 100 lignes par table. Le script fonctionne environ 3 secondes –

+0

Plusieurs processus avec le module 'concurrent.futures' peuvent accélérer ce processus si vous avez plus d'un cpu/core sous la main. Il y a un backport de ce module pour Python 2.7. – BlackJack

Répondre

0

Sans appartenir à votre algorithme, mais si vous exécutez 100 fichiers par jour et que le fichier de référence ne change pas, il peut être utile de créer un fichier maître (ou une base de données) indexé avec toutes les valeurs déjà calculées . Si les fichiers sont volumineux et qu'il y a beaucoup de données redondantes, cela pourrait augmenter considérablement vos performances au fil du temps.

0

s'il y a une chance que vous avez des entrées en double dans l'un des fichiers que vous pouvez trier les -uniq avant de traiter

+0

Merci pour la réponse. Nous n'avons pas de lignes en double dans les deux fichiers. –