2014-10-29 27 views
8

Pensavo che sarebbe stato semplice ma aveva qualche problema nel rintracciare un modo elegante per cercare contemporaneamente tutte le colonne in un dataframe per una corrispondenza di stringa parziale. Fondamentalmente come potrei applicare df['col1'].str.contains('^') a un intero dataframe in una sola volta e filtrare verso il basso su tutte le righe che contengono record contenenti la corrispondenza?Ricerca stringa in tutte le colonne e filtro di Pandas DataFrame

+0

Volete cercare un'intera dataframe piuttosto che solo una colonna specifica? – EdChum

+0

il metodo 'str.contains' è valido solo per la serie, quindi dovresti fare qualcosa come' per col in df: df [col] .str.contains ('^') ' – EdChum

risposta

16

Il metodo Series.str.contains prevede un modello regex (predefinito), non una stringa letterale. Pertanto str.contains("^") corrisponde all'inizio di qualsiasi stringa. Poiché ogni stringa ha un inizio, tutto corrisponde. Utilizzare invece str.contains("\^") per abbinare il letterale ^ carattere.

di controllare ogni colonna, è possibile utilizzare for col in df per scorrere i nomi delle colonne, e quindi chiamare str.contains su ogni colonna:

mask = np.column_stack([df[col].str.contains(r"\^", na=False) for col in df]) 
df.loc[mask.any(axis=1)] 

In alternativa, si potrebbe passare regex=False-str.contains per fare il test utilizzare il Python Operatore in; ma (in generale) l'uso della regex è più veloce.

+1

Ehi @unutbu, domanda per te . Perché usi 'np.column_stack 'quando puoi usare' pd.DataFrame (...). Transpose() '? – propjk007

+1

Quando 'mask' è un array NumPy booleano,' df.loc [mask] ' righe selezionate dove' mask' è True. Se 'mask' è un DataFrame, tuttavia, ' df.loc [mask] 'seleziona le righe da' df' il cui valore * index * corrisponde al valore di indice in 'mask' che corrisponde a un valore True. Questo allineamento degli indici è meraviglioso quando ne hai bisogno, ma rallenta le prestazioni quando non lo fai. Quindi, in breve, se non hai bisogno dell'indice , usa una matrice NumPy invece di un DataFrame. Inoltre, creando DataFrame è molto più lento della creazione dell'array NumPy quindi non c'è alcun vantaggio nell'uso di 'pd.DataFrame ([...]). T' qui. – unutbu

+1

Non ho pensato all'effetto prestazionale dell'approccio DataFrame. Era, più o meno, circa l'aggiunta di un altro modulo (numpy) e pensavo che usare le funzioni nella stessa libreria (panda) sarebbe stato meglio. Vedo che la tua metodologia a lungo termine è migliore. Grazie a @unutbu! – propjk007

1

Prova con:

df.apply(lambda row: row.astype(str).str.contains('TEST').any(), axis=1) 
Problemi correlati