pandas 和 "re" - 搜索全部和部分字符串

pandas and "re" - search for total and partial strings

这是 的扩展问题。我想在字符串中搜索全部和部分字符串,例如以下关键字 Series "w":

rigour*
*demeanour*
centre*
*arbour
fulfil

这显然意味着我想搜索像 rigor 和 rigour 这样的词s, endemeanour 和 demeanour s、center and centresharbour and arbour,然后fulfil。所以我的关键字列表是要查找的完整字符串和部分字符串的混合。我想在此 DataFrame "df":

上应用搜索
ID;name
01;rigour
02;rigours
03;endemeanour
04;endemeanours
05;centre
06;centres
07;encentre
08;fulfil
09;fulfill
10;harbour
11;arbour
12;harbours

到目前为止我尝试的是以下内容:

r = re.compile(r'.*({}).*'.format('|'.join(w.values)), re.IGNORECASE)

然后我构建了一个掩码来过滤 DataFrame:

mask = [m.group(1) if m else None for m in map(r.search, df['Tweet'])]

为了获得包含找到的关键字的新列:

df['keyword'] = mask

我期待的是以下结果 DataFrame:

ID;name;keyword
01;rigour;rigour
02;rigours;rigour
03;endemeanour;demeanour
04;endemeanours;demeanour
05;centre;centre
06;centres;centre
07;encentre;None
08;fulfil;fulfil
09;fulfill;None
10;harbour;arbour
11;arbour;arbour
12;harbours;None

这可以使用不带 * 的 w 列表。现在,为了 运行 re.compile 正确发挥作用,我在格式化关键字 w List of words with the * conditions 时遇到了几个问题。

任何帮助将不胜感激。

您的输入序列 w 似乎需要调整才能用作正则表达式模式,如下所示:

rigour.*
.*demeanour.*
centre.*
\b.*arbour\b
\bfulfil\b

请注意,正则表达式中的 * 用于处理它本身不起作用的内容。这意味着后面的任何内容都可以重复0次或多次。

另请注意,fulfilfulfill 的一部分,如果您想进行严格匹配,则需要告诉正则表达式。例如,通过使用 'word separator' - \b - 它只会捕获整个字符串。

以下是您的正则表达式为您提供所需结果的方式:

s = '({})'.format('|'.join(w.values))
r = re.compile(s, re.IGNORECASE)
r

re.compile(r'(rigour.*|.*demeanour.*|centre*|\b.*arbour\b|\bfulfil\b)', re.IGNORECASE)

您的替换代码可以使用 pandas .where 方法完成,如下所示:

df['keyword'] = df.name.where(df.name.str.match(r), None)
df

            ID          name       keyword
        0    1        rigour        rigour
        1    2       rigours       rigours
        2    3   endemeanour   endemeanour
        3    4  endemeanours  endemeanours
        4    5        centre        centre
        5    6       centres       centres
        6    7      encentre          None
        7    8        fulfil        fulfil
        8    9       fulfill          None
        9   10       harbour       harbour
        10  11        arbour        arbour
        11  12      harbours          None