熊猫数据框之间的部分字符串匹配

时间:2019-08-08 21:12:08

标签: python pandas

我见过关于部分字符串匹配合并herehere和其他地方的讨论,但是在包含超字符串而不是子字符串的表上没有关于如何做到这一点的讨论。

给出示例数据

df1 = pd.DataFrame({'uri': ['http://www.foo.com/index', 
                            'https://bar.net/directory', 
                            'www.baz.gov/aboutus']})
df2 = pd.DataFrame({'fqdn': ['www.foo.com',
                             'www.qux.mil']})
print(df1)

                         uri
0   http://www.foo.com/index
1  https://bar.net/directory
2        www.baz.gov/aboutus
print(df2)

          fqdn
0  www.foo.com
1  www.qux.mil

我的最终目标是从df1中删除在df2中包含 any 子字符串的行。在实际数据中,df1有几百万行,df2有几百行,df1中的任何给定行在df2中最多具有一个子字符串。

鉴于示例数据,我希望最终得到一个像这样的数据框

                         uri
0  https://bar.net/directory
1        www.baz.gov/aboutus

按照我的逻辑,中间步骤是生成

                         uri           fqdn
0   http://www.foo.com/index    www.foo.com
1  https://bar.net/directory         np.NaN
2        www.baz.gov/aboutus         np.NaN

但是我不知道如何检查df2中所有df1.apply()的值。


编辑:

虽然下面两个答案都起作用,但是通过编译正则表达式对象并使用extract,我在特定情况下获得了最快的结果:

import re

fqdn_list= re.compile(f"({'|'.join(df2.fqdn)})")

df1['fqdn'] = df1.uri.str.extract(fqdn_list)

2 个答案:

答案 0 :(得分:2)

这是您需要的吗? str.findall

df1.uri.str.findall(df2.fqdn.str.cat(sep='|')).str[0]
Out[192]: 
0    www.foo.com
1            NaN
2            NaN
Name: uri, dtype: object
#df1['fqdn']=df1.uri.str.findall(df2.fqdn.str.cat(sep='|')).str[0]

答案 1 :(得分:1)

使用管道(df2)作为分隔符将|中的字符串连接起来,分隔符是正则表达式中的or运算符。这样,我们可以检查df1是否包含这些字符串中的任何一个,并使用str.contains运算符~not删除它们;

m = ~df1['uri'].str.contains('|'.join(df2['fqdn']))
df1[m]

输出

                         uri
1  https://bar.net/directory
2        www.baz.gov/aboutus