2016-04-08 3 views
1

Ich habe eine Pandas DataFrame mit über einer Million Zeilen und ich muss alle eindeutigen Werte (für eine bestimmte Spalte) im Prozess der Normalisierung der Daten zu finden. Die Daten in der gegebenen Spalte sind vom Typ string - Stadtnamen repräsentierend - und ich bin schon weit gekommen, um die Daten zu normalisieren, indem ich bestimmte Schritte unterniedrigere alle Werte in der Spalte striping und pandas.core.frame.DataFrame.replace() mit regulären Ausdrücken verwende schien für die Daten offensichtlich.So finden Sie tatsächliche eindeutige Werte in Pandas DataFrame, die eine Regex

Eine Probe von dem, was ich habe (und ich mag erreichen) wie folgt zu finden:

In [1018]: sample 
Out[1018]: 
     0 
0  warsaw ## -> warsaw 
1  krakow ## -> krakow 
2 warszawa ## -> warsaw 
3 cracovie ## -> krakow 
4 warsawa ## -> warsaw 
5  krkow ## -> krakow 
6  krąków ## -> krakow 
7 krakowie ## -> krakow 
8  kraków ## -> krakow 
9 varşovia ## -> warsaw 
10 warschau ## -> warsaw 

nur viel größer Satz von Daten als diese, so dass ich für Variationen verschiedenen Städtenamen suchen muß reg verwenden Ausdrücke, um alle in den Datensätzen vorhandenen Versionen zu finden und mit der Normalisierung fortzufahren.

In [1023]: df.column_a.unique() 
Out[1023]: 
array(['warsaw', 'bydgoszcz', 'null', ..., 'kłodawa', 'kościelna wieś', 
    'poznań-jeżyce'], dtype=object) 

In [1024]: len(df.column_a.unique()) 
Out[1024]: 3798 

ich mit .str.contains() versucht habe, aber ich bin nur ein boolean für die Indizes erhalten, die hat - unter der definierten Spalte - Werte, die den angegebenen regulären Ausdruck entsprechen:

In [1029]: df.column_a.str.contains(r"\bwar.*") 
Out[1029]: 
0  True 
1  False 
2  False 
3  True 
4  False 
5  False 
6  False 
7  False 
8  False 
9  False 
10  False 
    ... 

Aber was ich bin Das Suchen nach ist, um die tatsächlichen Werte zu erhalten, die der gegebenen Regex entsprechen. Für das obige Beispiel würde Ich mag, um etwas zu bekommen wie:

['warsaw','warszawa','warsawa','warschau'] 
+1

Dies wird ein massiver Schmerz in der A $$ sein, müssen Sie senken -case, normalisiere die Schreibweisen, berechne irgendeine Art von Ähnlichkeit wie Levenshtein oder Jaccard, aber darüber hinaus hast du Einträge in verschiedenen Sprachen !! Wenn Sie Zugang zu einer Art von Wörterbuch haben, dann können Sie diese Einträge zuordnen und sie zu dem gleichen Stammwort normalisieren. – EdChum

+1

Ich könnte mir vorstellen, dass das alles mit Regex zu tun wäre * schrecklich * langsam. – n1c9

+0

@ n1c9 Running 'df.column_a = df.column_a.str.lower()' und 'df.column_a = df.column_a.str.strip()' ist in der Tat sehr schnell. Ich muss das nur einmal tun, nicht daran interessiert, wie gut die Lösung auf lange Sicht funktioniert. – Thanos

Antwort

1

Verwenden boolean Indizierung - siehe document

In [143] df[df.column_a.str.contains(r'\bwar.*')] 
    Out [143] 
    0  warsaw 
    2 warszawa 
    4 warsawa 
    10 warschau 

Wenn Nullwerte sind dann dies tun:

df[pd.notnull(df.column_a) & df.column_a.str.contains(r'\bwar.*')] 
+0

Danke! Ich habe einen Fehler bekommen, der folgendes versucht: 'ValueError: kann nicht mit Vektor indexieren, der NA/NaN-Werte enthält'. Ich vermute, ich sollte versuchen, alle NaN-Werte durch leere Strings oder ähnliches zu ersetzen. – Thanos

+0

Aktualisieren Sie die Antwort für - was ist, wenn Nullwerte vorhanden sind – Abbas

0

ich jetzt habe einen Weg gefunden, um eine Suche auszuführen eindeutige Werte in einer Spalte Dataframe zurückzukehren. Die Lösung ist extract die Werte stattdessen.

Für das Problem, wie oben beschrieben, habe ich str.extract() statt, was str.contains()

verwendet
In [1311]: df.column_a.str.extract(r"\b(war.*)").unique() 
Out[1311]: 
array(['warsaw', nan, 'waraszawa', 'warszawskiej', 'warszawy', 'warzawa', 
    'warsza', 'warrszawa', 'warzszawa', 'warszawan', 'warszawie', 
    'warwszawa', 'warszawski', 'warzno 84-208', 'warasza, wola', 
    'warszawskie', 'warzsawa', 'warzno', 'warszawa', 'warszwa', 'warsawa'], dtype=object) 

Es könnte eine bessere Lösung sein, aber das ist sicher ein.

Verwandte Themen