Pandas列使用re.search正则匹配结果数量不符且匹配异常问题
问题分析与解决
问题现象
运行以下代码后,预期得到9条匹配结果:其中最后一条'sypid_09_2_3match'应该匹配'match',第5条'hello'不应匹配。但实际结果仅生成5条,且匹配逻辑完全错误,即使传入列表而非DataFrame列,结果也一致。
import re import pandas as pd df = pd.DataFrame({"Name": ['match', '1234match_sypid_1234_34_7', 'matchsypid_1234_56_7', 'Hellow', 'hello', 'oaoaooo', 'ciao', 'salut','sypid_09_2_3match']}) print(df.shape) # => (9, 1) mask = [re.search(p,s) for p,s in zip(r"match", df['Name'])] print(len(mask)) # => 5 print(mask) # =>[<re.Match object; span=(0, 1), match='m'>, <re.Match object; span=(5, 6), match='a'>, <re.Match object; span=(2, 3), match='t'>, None, <re.Match object; span=(0, 1), match='h'>] mask = [True if x is not None else False for x in mask] print(mask) # => [True, True, True, False, True]
错误原因
zip(r"match", df['Name'])是核心问题:字符串r"match"会被迭代拆分为单个字符'm'、'a'、't'、'c'、'h',然后和df['Name']的前5个元素一一配对,最终只生成5个元素的列表。- 每个配对用单个字符去匹配对应位置的字符串,比如用
'm'匹配第一个元素'match',自然能匹配到'm',这就导致了完全不符合预期的错误匹配。
解决方案
方法1:正确遍历每个字符串
直接遍历df['Name']的每个元素,用同一个正则表达式r"match"去匹配:
import re import pandas as pd df = pd.DataFrame({"Name": ['match', '1234match_sypid_1234_34_7', 'matchsypid_1234_56_7', 'Hellow', 'hello', 'oaoaooo', 'ciao', 'salut','sypid_09_2_3match']}) print(df.shape) # => (9, 1) # 遍历每个字符串,检查是否包含'match' mask = [re.search(r"match", s) is not None for s in df['Name']] print(len(mask)) # => 9 print(mask) # => [True, True, True, False, False, False, False, False, True]
方法2:使用Pandas原生方法(更高效)
利用Pandas的str.contains方法直接生成布尔掩码,无需手动遍历:
import pandas as pd df = pd.DataFrame({"Name": ['match', '1234match_sypid_1234_34_7', 'matchsypid_1234_56_7', 'Hellow', 'hello', 'oaoaooo', 'ciao', 'salut','sypid_09_2_3match']}) mask = df['Name'].str.contains(r"match") print(len(mask)) # => 9 print(mask.tolist()) # => [True, True, True, False, False, False, False, False, True]
内容的提问来源于stack exchange,提问作者Nicoswow
相关产品推荐
相关产品推荐

