# find rows in `df1` which contain "foo" followed by something
df1[df1['col'].str.contains(r'foo(?!$)')]
col
1 foobar
有时不需要正则表达式搜索,所以指定regex=False来禁用它
#select all rows containing "foo"
df1[df1['col'].str.contains('foo', regex=False)]
# same as df1[df1['col'].str.contains('foo')] but faster.
col
0 foo
1 foobar
就性能而言,正则表达式搜索比子字符串搜索慢:
df2 = pd.concat([df1] * 1000, ignore_index=True)
%timeit df2[df2['col'].str.contains('foo')]
%timeit df2[df2['col'].str.contains('foo', regex=False)]
6.31 ms ± 126 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
2.8 ms ± 241 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
如果不需要,请避免使用基于正则表达式的搜索
寻址ValueErrors
有时,对结果执行子字符串搜索和筛选将导致
ValueError: cannot index with vector containing NA / NaN values
def try_search(p, x):
try:
return bool(p.search(x))
except TypeError:
return False
p = re.compile(regex_pattern)
df1[[try_search(p, x) for x in df1['col']]]
col
1 foobar
f = np.vectorize(lambda haystack, needle: needle in haystack)
f(df1['col'], 'foo')
# array([ True, True, False, False])
df1[f(df1['col'], 'foo')]
col
0 foo abc
1 foobar
可能的正则表达式解决方案:
regex_pattern = r'foo(?!$)'
p = re.compile(regex_pattern)
f = np.vectorize(lambda x: pd.notna(x) and bool(p.search(x)))
df1[f(df1['col'])]
col
1 foobar
基于github问题#620,您很快就可以执行以下操作:
更新:vectorized string methods (i.e., Series.str)在pandas 0.8.1及更高版本中提供
这篇文章是写给想读的读者的
…并希望了解更多关于哪些方法应优于其他方法的信息
(旁白:我已经看到很多关于类似主题的问题,我想把这个留在这里会很好。)
基本子串搜索
^{} 可用于执行子字符串搜索或基于正则表达式的搜索。除非显式禁用,否则搜索默认为基于正则表达式
下面是一个基于正则表达式的搜索示例
有时不需要正则表达式搜索,所以指定
regex=False
来禁用它就性能而言,正则表达式搜索比子字符串搜索慢:
如果不需要,请避免使用基于正则表达式的搜索
寻址
ValueError
s有时,对结果执行子字符串搜索和筛选将导致
这通常是因为对象列中存在混合数据或NAN
任何不是字符串的东西都不能应用字符串方法,因此结果是NaN(自然)。在这种情况下,指定
na=False
忽略非字符串数据如何一次将其应用于多个列?} :
答案在问题中。使用^{
下面的所有解决方案都可以使用列方式
apply
方法“应用”到多个列(在我的书中这是可以的,只要你没有太多的列)如果您有一个包含混合列的数据框,并且只想选择对象/字符串列,请查看^{}
多个子串搜索
这最容易通过使用正则表达式或管道的正则表达式搜索来实现
您还可以创建术语列表,然后将其合并:
有时,如果术语中的字符可以解释为regex metacharacters,则明智的做法是对术语进行转义。如果您的术语包含以下任何字符
然后,您需要使用^{} 来转义它们:
re.escape
具有转义特殊字符的效果,因此它们被逐字处理匹配整个单词
默认情况下,子字符串搜索将搜索指定的子字符串/模式,而不管它是否为完整单词。为了只匹配完整的单词,我们需要在这里使用正则表达式,特别是,我们的模式需要指定单词边界(
\b
)比如说,
现在考虑,
v/s
多个整词搜索
与上面类似,除了我们向连接模式添加单词边界(
\b
)其中
p
看起来像这样一个很好的选择:使用List Comprehensions
因为你可以And you should!它们通常比字符串方法快一点,因为字符串方法很难矢量化,并且通常有循环实现
而不是
在列表comp中使用
in
运算符而不是
在列表comp中使用^{} (缓存正则表达式)+^{}
如果“col”有nan,那么
使用
部分字符串匹配的更多选项:^{} ,^{} ,^{} 。
除了
str.contains
和列表理解之外,您还可以使用以下替代方法np.char.find
支持子串仅搜索(阅读:无正则表达式)
np.vectorize
这是一个围绕循环的包装器,但是比大多数pandas
str
方法的开销要小可能的正则表达式解决方案:
DataFrame.query
通过python引擎支持字符串方法。这并没有提供明显的性能优势,但如果您需要动态生成查询,这仍然很有用
有关
query
和eval
方法系列的更多信息,请参见Dynamic Expression Evaluation in pandas using pd.eval()推荐使用优先级
str.contains
,因为它简单且易于处理NAN和混合数据np.vectorize
df.query
我尝试了上述建议的解决方案:
并得到一个错误:
可以将NA值转换为
False
,如下所示:相关问题 更多 >
编程相关推荐