匹配模式的数据帧列之间的字符串搜索

2024-09-28 19:05:56 发布

您现在位置:Python中文网/ 问答频道 /正文

我有一个包含字符串的表

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 in-column regex\u search搜索列字符串?你知道吗


Tags: key字符串redataframesearch参数regexpd
3条回答

这将得到你的结果,但很慢。你知道吗

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)

您可以组合数据帧,然后使用apply函数执行正则表达式搜索。在本例中,我将您的re数据帧重命名为r,因为re是模块的名称。首先执行两个数据帧的笛卡尔积。然后在lambda中,在每一行中计算正则表达式regex_search,并输出一个布尔值,指示如果表达式在strings_to_search中存在,搜索是否生成True;如果表达式不存在,则生成False。最后,将数据帧过滤到匹配发生的位置,对strings_to_search进行分组,并生成所有匹配regex_search的列表。你知道吗

import pandas as pd
import re

a["idx"] = 1
r["idx"] = 1
df = a.merge(r, on="idx").drop("idx", axis=1)

df["output"] = df.apply(lambda x: bool(re.compile(x["regex_search"]).search(x["strings_to_search"])), axis=1)

df[df["output"] == True].groupby("strings_to_search")["regex_search"].apply(list)

如果要将每个字符串与每个正则表达式进行比较,请使用list和重新匹配地址:

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).*$

相关问题 更多 >