2013-03-10 13 views
72

Ich möchte sauber filtern einen Datenrahmen mit Regex auf einer der Spalten.So filtern Sie Zeilen in Pandas von Regex

Für ein konstruiertes Beispiel:

In [210]: foo = pd.DataFrame({'a' : [1,2,3,4], 'b' : ['hi', 'foo', 'fat', 'cat']}) 
In [211]: foo 
Out[211]: 
    a b 
0 1 hi 
1 2 foo 
2 3 fat 
3 4 cat 

Ich mag die Zeilen diejenigen filtern, die mit f mit einem regulären Ausdruck starten. Zuerst gehen:

In [213]: foo.b.str.match('f.*') 
Out[213]: 
0 [] 
1 () 
2 () 
3 [] 

Das ist nicht zu schrecklich nützlich. Dies wird jedoch mir meine boolean Index erhalten:

In [226]: foo.b.str.match('(f.*)').str.len() > 0 
Out[226]: 
0 False 
1  True 
2  True 
3 False 
Name: b 

So konnte ich dann durch meine Einschränkung tun:

In [229]: foo[foo.b.str.match('(f.*)').str.len() > 0] 
Out[229]: 
    a b 
1 2 foo 
2 3 fat 

Das hat mich künstlich eine Gruppe in die regex obwohl setzen macht, und scheint, wie vielleicht auch nicht die sauberer Weg zu gehen. Gibt es einen besseren Weg, dies zu tun?

+3

Wenn Sie sich nicht auf reguläre Ausdrücke fest gebunden, 'foo [foo.b.str.startswith ("f")] 'wird funktionieren. – DSM

+0

IMHO Ich denke 'foo [foo.b.str.match ('(f. *)'). Str.len()> 0]' ist eine ziemlich gute Lösung! Anpassbarer und nützlicher als Startswith, weil es die Vielseitigkeit von Regex in sich vereint. –

Antwort

91

Verwenden contains statt:

In [10]: df.b.str.contains('^f') 
Out[10]: 
0 False 
1  True 
2  True 
3 False 
Name: b, dtype: bool 
+5

Wie kann der Boolean invertiert werden? Fand es: http://stackoverflow.com/questions/15998188/wie-kann--ist-die-element-wise-logical-not-of-a-pandas-series – dmeu

13

Multiple Spalte Suche mit Datenrahmen:

frame[frame.filename.str.match('*.'+MetaData+'.*') & frame.file_path.str.match('C:\test\test.txt')] 
+0

'frame'? und 'C: \ test \ test.txt''? Es scheint, als ob du eine andere Frage beantwortest. –

+0

Rahmen ist df. Es bezieht sich auf die gleiche Frage, aber es beantwortet, wie mehrere Spalten ('Dateiname' und 'Dateipfad') in einem Zeilencode gefiltert werden. –

6

Dies kann ein bisschen spät, aber das ist jetzt einfacher in Pandas zu tun. Sie können eine Übereinstimmung mit as_indexer=True aufrufen, um boolesche Ergebnisse zu erhalten. Dies ist dokumentiert (zusammen mit dem Unterschied zwischen match und contains) here.

5

Es gibt bereits eine String-Handling-Funktion Series.str.startwith().

Sie sollten versuchen, foo[foo.b.str.startswith('f')].

Ergebnis:

a b 
1 2 foo 
2 3 fat 

Ich denke, was Sie erwarten.

0

schreiben eine boolian Funktion, die überprüft die Regex und den Einsatz auf dem

foo Spalte anwenden [foo [ 'b']. Anwenden (regex_function)]

Verwandte Themen