【问题标题】:pandas and "re" - search for total and partial stringspandas 和 "re" - 搜索全部和部分字符串
【发布时间】:2015-01-28 17:19:21
【问题描述】:

这是来自this topic 的扩展问题。我想在字符串中搜索全部和部分字符串,例如以下关键字系列“w”:

rigour*
*demeanour*
centre*
*arbour
fulfil

这显然意味着我想搜索严格和严谨s、en风度和风度s、中心和中心s,h乔木和乔木,完成。因此,我拥有的关键字列表是要查找的完整字符串和部分字符串的组合。我想在这个 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 列表。现在我在格式化关键字 w 带有 * 条件的单词列表时遇到了几个问题,以便正确运行 re.compile 函数。

任何帮助将不胜感激。

【问题讨论】:

    标签: python regex string pandas


    【解决方案1】:

    看起来您的输入序列w 需要调整为像这样用作正则表达式模式:

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

    请注意,正则表达式中的* 会追踪它无法自行运行的东西。这意味着它后面的任何东西都可以重复0次或多次。

    还要注意fulfilfulfill 的一部分,如果你想要严格匹配,你需要告诉正则表达式。例如,通过使用“单词分隔符” - \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
    

    【讨论】:

    • 非常感谢!只有一个问题,rigour.* 和 center* 有什么区别?他们最后应该有相同的“.*”部分吗?
    • 很好看。是的,他们应该有相同的结尾.*。我已经更正了这个错字。
    • 非常感谢。即使在搜索较长的字符串时,要正确获取新的“关键字”列,我建议使 mask = [m.group(1) if m else None for m in map(r.search, df['name'])] 然后 df['Keyword'] = mask 应该返回在每个字符串中找到的正确关键字。
    猜你喜欢
    • 2018-11-23
    • 1970-01-01
    • 2018-09-29
    • 2016-01-19
    • 1970-01-01
    • 2015-05-02
    • 2021-06-28
    • 2015-11-13
    • 2017-07-13
    相关资源
    最近更新 更多