匹配模式的DataFrame列之间的字符串搜索

时间:2019-02-21 11:34:55

标签: python pandas

我有一个包含字符串的表

a = pd.DataFrame({"strings_to_search" : ["AA1 BB2 CVC GF2","AR1 KP1","PL3 4OR 91K GZ3"]})

和一个带有搜索参数的正则表达式

re = pd.DataFrame({"regex_search" : ["^(?=.*AA1).*$", "^(?=.*AR1)(?=.*PL3).*$", "^(?=.*4OR)(?=.*GZ3).*$"]})

我的目标是将字符串与搜索参数匹配(如果它是字符串的一部分)。 我想将每个字符串与每个模式进行比较,并加入匹配的字符串模式,如下所示:

| AA1 BB2 CVC GF2 | ^(?=.*AA1).*$
| PL3 4OR 91K GZ3 | ^(?=.*4OR)(?=.*GZ3).*$

在大熊猫中有什么办法吗?我已经使用rlike函数在sparkSQL中实现了类似的功能,但是在连接大表时spark的效果不太好。

由于pandas没有rlike函数,因此我的方法是对两个表进行交叉连接,然后比较各列。

a["key"] = 0
re["key"] = 0
res = a.merge(re, on="key")

但是如何在regex_search列中使用正则表达式搜索string_to_search列?

3 个答案:

答案 0 :(得分:3)

您可以组合数据框,然后使用apply函数执行正则表达式搜索。在本示例中,由于re是模块的名称,因此我将r数据帧重命名为re。首先执行两个DataFrame的笛卡尔积。然后在lambda中,对每一行的正则表达式regex_search进行评估,并返回一个布尔输出,指示如果表达式存在于True或{{中,则搜索是否产生strings_to_search 1}}(如果表达式不存在)。最后,将DataFrame过滤到匹配发生的位置,对False进行分组,并生成所有匹配的strings_to_search的列表。

regex_search

答案 1 :(得分:1)

如果您想将每个字符串与每个正则表达式进行比较,请使用列表理解和重新匹配:

import re
result = [string+' | '+reg for reg in r['regex_search'] for string in a['strings_to_search']
          if re.compile(reg).match(string)]
result
['AA1 BB2 CVC GF2|^(?=.*AA1).*$', 'PL3 4OR 91K GZ3|^(?=.*4OR)(?=.*GZ3).*$']

如果您要一个新的数据框:

new_df = pd.DataFrame({'matches': result })
new_df
         matches
0   AA1 BB2 CVC GF2|^(?=.*AA1).*$
1   PL3 4OR 91K GZ3|^(?=.*4OR)(?=.*GZ3).*$

答案 2 :(得分:0)

这将为您带来结果,但速度很慢。

import re
import pandas as pd

a = pd.DataFrame({"strings_to_search" : ["AA1 BB2 CVC GF2","AR1 KP1","PL3 4OR 91K GZ3"]})
b = pd.DataFrame({"regex_search" : ["^(?=.*AA1).*$", "^(?=.*AR1)(?=.*PL3).*$", "^(?=.*4OR)(?=.*GZ3).*$"]})

a.insert(1,'regex','')

for item in b.regex_search:
    for s in a.strings_to_search:
        if(re.match(item,s)):
            a.regex.loc[a.strings_to_search == s] = item

print(a)