2014-10-29 114 views
8

認爲這將是直接的,但有一些麻煩追蹤優雅的方式來同時搜索數據框中的所有列以進行部分字符串匹配。基本上,我如何將df['col1'].str.contains('^')一次應用於整個數據幀,並過濾到包含匹配記錄的任何行?在所有Pandas DataFrame列和過濾器中搜索字符串

+0

你想搜索整個數據幀,而不僅僅是一個特定的列? – EdChum 2014-10-29 20:45:13

+0

'str.contains'方法僅適用於Series,因此您必須執行類似於'df:df [col] .str.contains('^')col的操作' – EdChum 2014-10-29 20:48:03

回答

16

Series.str.contains方法需要正則表達式模式(默認情況下),而不是文字字符串。因此str.contains("^")匹配任何字符串的開頭。由於每個字符串都有一個開始,所有匹配。請使用str.contains("\^")來匹配文字^字符。

要檢查每一列,你可以使用for col in df通過列名進行迭代,然後調用str.contains每列:

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

或者,你可以通過regex=Falsestr.contains使測試使用Python in運算符;但是(通常)使用正則表達式會更快。

+1

嘿@unutbu,您的問題。爲什麼在使用'pd.DataFrame(...)。轉置()'時使用'np.column_stack'? – propjk007 2015-12-01 17:42:37

+1

當'mask'是一個布爾型的NumPy數組時,'df.loc [mask]' 選擇了'mask'爲True的行。然而,如果'mask'是一個DataFrame,那麼'df.loc [mask]'從'df'中選擇那些* index *值與 'mask'中的索引值相匹配的行,它對應於一個True值。當你需要時,這種索引的對齊方式非常棒,但是當你不需要時,會降低性能。因此,簡而言之,如果您不需要索引 ,請使用NumPy數組而不是DataFrame。另外,創建 DataFrame比創建NumPy數組慢得多,所以 在這裏使用'pd.DataFrame([...])。T'沒有任何優勢。 – unutbu 2015-12-01 18:52:51

+1

我沒有想到DataFrame方法的性能影響。或多或少,增加另一個Module(numpy),並認爲使用同一個庫(熊貓)中的函數會更好。我明白你的方法在長遠來看是更好的。謝謝@unutbu! – propjk007 2015-12-01 22:02:03

1

嘗試:

df.apply(lambda row: row.astype(str).str.contains('TEST').any(), axis=1) 
相關問題