2016-04-20 8 views
0

Ich habe den folgenden Pandas Datenrahmen in Python3.5:Verwenden iterrows in Pandas Mismatches zwischen Strings zu finden, Fehler

import pandas as pd 
df = pd.Dataframe(...) 
print(df) 

die

string1  string2 
'abcdefg...' 'abcSefg...' 
'Iknowhow...' 'Eknowhow...' 
'Thecatis...' 'Thekatis...' 
... 

gibt wollte ich zuerst den Standort von Mismatches finden zwischen string1 und string2 und an den Dataframe df anhängen. Ich benutze diesen Code:

df["different_positions"] = [[i for i in range(len(row.string2)) 
    if row.string1[i] != row.string2[i]] for _, row in df.iterrows()] 

Das wird mir alle Positionen geben, die Mismatches auftreten. Nun möchte ich eine separate Spalte, die jeden Buchstaben des Mismatch ausgibt. Zum Beispiel in string2 gibt es eine S anstelle ein d in der ersten Reihe, ein E statt I in der zweiten Reihe, usw.

ich der Code gedacht, jedoch

df["different_letters"] = [[i for i in row.string2 
    if row.string1[i] != row.string2[i]] for _, row in df.iterrows()] 

sein, Es scheint, das ist nicht korrekt. Ich erhalte eine NameError bei for _, row, das heißt

NameError: name 'i' is not defined 

Wie kann ich Ausgang den nicht passenden Brief an unpassender Position entsprechen?

+0

Was ist die Ausgabe, die Sie erhalten? –

+0

@AkshatMahajan Für die Spalte 'different_positions' erhalte ich eine Liste aller nicht übereinstimmenden Positionen, z. "[5, 11, 28, 81]". Für den Fehler siehe oben Bearbeiten. – ShanZhengYang

Antwort

1

String-Iteration gibt Zeichen, keine Indizes zurück. Mit anderen Worten, i for i in row.string2 wird durch die Zeichen von row.string2, nicht die entsprechenden Indizes gehen.

So

df["different_letters"] = [[i for i in row.string2 
if row.string1[i] != row.string2[i]] for _, row in df.iterrows()] 

ist falsch, da Sie effektiv sind zu fragen, was row.string1['a'] ist, wenn row.string1 eine a enthält. String-Indizes müssen ganze Zahlen sein.

Stattdessen möchten Sie

df["different_letters"] = [[j for i, j in enumerate(row.string2) 
if row.string1[i] != row.string2[i]] for _, row in df.iterrows()] 

enumerate können Sie durchlaufen sowohl der Index und das entsprechende Element in einem iterable tun. Hier ist j das entsprechende Zeichen, i ist sein Index, und Sie können jetzt nach Index vergleichen, aber nur das entsprechende Zeichen zurückgeben.

+0

Danke! Das funktioniert perfekt. Könnten Sie mir übrigens die Syntax 'for _, row in ...' erklären? Ich benutze es, aber ich bin nicht ganz sicher, warum wir '_' eingeben. Steht das für "rowindex"? – ShanZhengYang

+0

@ShanZhengYang Nein, das _ _ ist nur ein willkürliches zufälliges Zeichen. Sie können es ohne Schwierigkeiten in "foo" oder "bar" ändern. Die Konvention besteht darin, '_' für Variablen zu verwenden, deren Werte wir nicht benötigen, aber trotzdem übernehmen müssen. 'df.iterrows() 'gibt' rowindex' und 'row' zurück - da wir' rowindex' nicht brauchen, bezeichnen wir es einfach mit '_' und gehen weiter. –

+0

Auch, würde als akzeptierte Antwort markiert werden, wenn dies Ihnen geholfen hat. –

Verwandte Themen