2013-03-10 10 views
72

Vorrei filtrare in modo pulito un dataframe usando espressioni regolari su una delle colonne.Come filtrare le righe in Panda per regex

Per un esempio inventato:

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 

voglio filtrare le righe a quelli che iniziano con f utilizzando un'espressione regolare. Prima vai:

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

Questo non è troppo terribilmente utile. Tuttavia questo mi otterrà il mio indice booleano:

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

così ho potuto poi fare la mia restrizione:

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

Questo mi fa mettere artificialmente un gruppo nella regex però, e sembra che forse non il pulito modo di andare. C'è un modo migliore per farlo?

+3

Se non sei sposata a regex, 'foo [foo.b.str.startswith ("f")] 'funzionerà. – DSM

+0

IMHO Penso che 'foo [foo.b.str.match ('(f. *)'). Str.len()> 0]' è una soluzione abbastanza buona! Più personalizzabile e utile di startswith perché racchiude in sé la versatilità della regex. –

risposta

91

Uso contains invece:

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

Come può essere invertito il booleano? Trovato: http://stackoverflow.com/questions/15998188/how-can-i-obtain-the-element-wise-logical-not-of-a-pandas-series – dmeu

13

ricerca colonna multipla con dataframe:

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

'frame'? e ''C: \ test \ test.txt''? Sembra che tu stia rispondendo a una domanda diversa. –

+0

frame is df. è relativo alla stessa domanda, ma risponde come filtrare più colonne ("nome file" e "percorso file") in un codice di riga. –

6

Questo può essere un po 'in ritardo, ma questo è ora più facile da fare in Panda. Puoi chiamare la partita con as_indexer=True per ottenere risultati booleani. Questo è documentato (insieme alla differenza tra match e contains) here.

5

Esiste già una funzione di gestione delle stringhe Series.str.startwith().

Si consiglia di provare foo[foo.b.str.startswith('f')].

Risultato:

a b 
1 2 foo 
2 3 fat 

Penso che quello che ci si aspetta.

0

scrivere una funzione boolian che controlla l'espressione regolare e l'uso si applicano sulla colonna

foo [pippo [ 'b']. Applicare (regex_function)]

Problemi correlati