2014-10-29 137 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) 
相关问题