web-dev-qa-db-de.com

So filtern Sie Reihen in Pandas nach Regex

Ich möchte einen Datenrahmen sauber mit Regex in einer der Spalten filtern.

Für ein erfundenes 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 möchte die Zeilen nach denen filtern, die mit f beginnen, indem Sie einen regulären Ausdruck verwenden. Zuerst gehen:

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

Das ist nicht besonders nützlich. Dies bringt mir jedoch meinen booleschen Index:

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

So könnte ich meine Einschränkung dann machen durch:

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

Das bringt mich dazu, eine Gruppe künstlich in den Regex einzubringen, und scheint vielleicht nicht der saubere Weg. Gibt es einen besseren Weg, dies zu tun?

105
justinvf

Verwenden Sie enthält stattdessen:

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

Mehrspaltige Suche mit Datenrahmen:

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

Es gibt bereits eine Stringbehandlungsfunktion Series.str.startwith()

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

Ergebnis:  

a   b
1   2   foo
2   3   fat

Ich denke was du erwartest.

9
Erkan Şirin

Dies kann etwas spät sein, ist aber jetzt in Pandas einfacher. Sie können match mit as_indexer=True aufrufen, um boolesche Ergebnisse zu erhalten. Dies ist dokumentiert (zusammen mit dem Unterschied zwischen match und contains) hier .

9
Michael Siler

Vielen Dank für die großartige Antwort @ user3136169. Hier ein Beispiel, wie dies auch beim Entfernen von NoneType-Werten möglich ist.

def regex_filter(val):
    if val:
        mo = re.search(regex,val)
        if mo:
            return True
        else:
            return False
    else:
        return False

df_filtered = df[df['col'].apply(regex_filter)]
6
sparrow

Schreiben Sie eine boolesche Funktion, die den regulären Ausdruck prüft, und verwenden Sie in der Spalte "apply"

foo[foo['b'].apply(regex_function)]
4
user3136169

str Slice verwenden 

foo[foo.b.str[0]=='f']
Out[18]: 
   a    b
1  2  foo
2  3  fat
0
Wen-Ben