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

时间:2016-04-15 20:50:22

标签: 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的运算符(检索所有5行):

df[df['string_col'].str.contains('foo|bar')]

我以为我可以遍历我的列表,拆分并加入'&'做类似的事情(我错误地认为这将检索4行):

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

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

谢谢!

2 个答案:

答案 0 :(得分:1)

您必须使用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

答案 1 :(得分:1)

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

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