2014-10-29 20 views
8

Pomyślałem, że byłoby to proste, ale miałem problem ze znalezieniem eleganckiego sposobu wyszukiwania wszystkich kolumn w ramce danych w tym samym czasie dla częściowego dopasowywania ciągów znaków. Zasadniczo jak mogę zastosować df['col1'].str.contains('^') do całej ramka danych naraz i odfiltrować do wszystkich wierszy, które mają rekordy zawierające dopasowanie?Wyszukaj ciąg we wszystkich kolumnach DataFrame i filtru Pandy

+0

Chcesz przeszukać całą dataframe aniżeli tylko określonej kolumnie? – EdChum

+0

Metoda 'str.contains' jest poprawna tylko dla Serii, więc musiałbyś zrobić coś takiego jak' dla col w df: df [col] .str.contains ('^') ' – EdChum

Odpowiedz

16

Metoda oczekuje wzoru regex (domyślnie), a nie literału. Dlatego str.contains("^") dopasowuje początek dowolnego ciągu znaków. Ponieważ każdy ciąg ma początek, wszystko się zgadza. Zamiast tego użyj str.contains("\^"), aby dopasować literał do postaci ^.

Aby sprawdzić każdą kolumnę, można użyć for col in df iterację nazwy kolumn, a następnie zadzwonić str.contains na każdej kolumnie:

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

Alternatywnie, można przejść regex=False do str.contains zrobić test używać Pythona in operator; ale (na ogół) używanie regex jest szybsze.

+1

Hej @unutbu, pytanie do ciebie . Dlaczego używasz 'np.column_stack ', kiedy możesz użyć' pd.DataFrame (...). Transpose() '? – propjk007

+1

Gdy 'maska' jest boolowską tablicą NumPy,' df.loc [maska] ' wybranych wierszy, w których' maska' jest True. Jeśli 'mask' jest ramką DataFrame, to następnie ' df.loc [maska] 'wybiera wiersze z' df', których * indeks * odpowiada wartości indeksu w 'masce', która odpowiada wartości True. To wyrównanie indeksów jest wspaniałe, gdy jest potrzebne, ale spowalnia wydajność, gdy tego nie potrzebujesz. Krótko mówiąc, jeśli nie potrzebujesz indeksu, użyj tablicy NumPy zamiast DataFrame. Ponadto tworzenie ramki DataFrame jest znacznie wolniejsze niż tworzenie tablicy NumPy, więc nie ma żadnej korzyści z używania 'pd.DataFrame ([...]) .T' tutaj. – unutbu

+1

Nie myślałem o wpływie wydajności na podejście DataFrame. W mniejszym lub większym stopniu chodziło o dodanie kolejnego modułu (numpy) i pomyślałem, że korzystanie z funkcji w tej samej bibliotece (panda) byłoby lepsze. Widzę, że twoja metodologia na dłuższą metę jest lepsza. Dzięki @unutbu! – propjk007

1

spróbuj:

df.apply(lambda row: row.astype(str).str.contains('TEST').any(), axis=1) 
Powiązane problemy