Python 匹配列中未知数量的字符串元素

Python 匹配列中未知数量的字符串元素,python,pandas,Python,Pandas,我有一个字符串列表,需要对数据框中的某一列进行搜索: search_strings = ['foo bar', 'bar such foo', 'very wow foo'] 我试图检索数据框中与列表中每个字符串中的单词顺序匹配的行。数据帧可能如下所示: ID string_col 1 foo bar 2 bar foo 3 foo very bar 4 bar such foo 5 foo wow very 我很高兴地发现,我可以将“|”运算符与str.contains一起使用(

我有一个字符串列表,需要对数据框中的某一列进行搜索:

search_strings = ['foo bar', 'bar such foo', 'very wow foo']
我试图检索数据框中与列表中每个字符串中的单词顺序匹配的行。数据帧可能如下所示:

ID string_col
1  foo bar
2  bar foo
3  foo very bar
4  bar such foo
5  foo wow very
我很高兴地发现,我可以将“|”运算符与str.contains一起使用(检索所有5行):

我想我可以循环浏览我的列表,拆分并使用“&”连接它们,以执行类似的操作(我错误地认为这将检索到4行):

然而,事实证明,这不是你能做到的。你知道如何根据字符串列表轻松检索匹配列,每个字符串的字数未知吗


谢谢

您必须使用
str.contains
通过2个条件,并将它们用括号括起来,然后使用
&

In [11]:
df[df['string_col'].str.contains('foo') & df['string_col'].str.contains('bar')]

Out[11]:
   ID    string_col
0   1       foo bar
1   2       bar foo
2   3  foo very bar
3   4  bar such foo

您可以对拆分字符串使用列表理解,确保所有目标词都存在:

words = ['foo', 'bar']
df['word_match'] = [all(word in values for word in words) 
                    for values in df.string_col.str.split(" ")]

>>> df
   ID    string_col word_match
0   1       foo bar       True
1   2       bar foo       True
2   3  foo very bar       True
3   4  bar such foo       True
4   5       foo wow      False
计时

%timeit df['word_match'] = [all(word in values for word in words) for values in df.string_col.str.split(" ")]
1000 loops, best of 3: 320 µs per loop

%timeit df['word_match'] = df[df['string_col'].str.contains('foo') & df['string_col'].str.contains('bar')]
1000 loops, best of 3: 1.23 ms per loop
在较大的数据集上,第二种方法略优于:

df2 = pd.concat([df]*10000, ignore_index=True)

%timeit df2['word_match'] = [all(word in values for word in words) for values in df2.string_col.str.split(" ")]
10 loops, best of 3: 70.9 ms per loop

%timeit df2['word_match'] = df2[df2['string_col'].str.contains('foo') & df2['string_col'].str.contains('bar')]
10 loops, best of 3: 63.7 ms per loop

谢谢我对我的文章进行了更具体的编辑——我不知道需要匹配多少单词。你只是定义了多个掩码,然后
&
它们都是
foo\u mask=df['string\u col'].str.contains('foo')bar\u mask=df['string\u col'].str.contains('bar')filtered=df[foo&bar]
您可以成功构建这样的掩码,并将它们组合起来,但您可能希望使用
all(单词集合(值)…
%timeit df['word_match'] = [all(word in values for word in words) for values in df.string_col.str.split(" ")]
1000 loops, best of 3: 320 µs per loop

%timeit df['word_match'] = df[df['string_col'].str.contains('foo') & df['string_col'].str.contains('bar')]
1000 loops, best of 3: 1.23 ms per loop
df2 = pd.concat([df]*10000, ignore_index=True)

%timeit df2['word_match'] = [all(word in values for word in words) for values in df2.string_col.str.split(" ")]
10 loops, best of 3: 70.9 ms per loop

%timeit df2['word_match'] = df2[df2['string_col'].str.contains('foo') & df2['string_col'].str.contains('bar')]
10 loops, best of 3: 63.7 ms per loop