【问题标题】:Pandas to match column contents to keywords (with spaces and brackets )Pandas 将列内容与关键字匹配(带空格和括号)
【发布时间】:2020-02-01 12:51:14
【问题描述】:

数据框中的列包含我要匹配的关键字。

我想检查每列是否包含任何关键字。如果是,请打印出来。

尝试如下:

import pandas as pd
import re

Keywords = [

"Caden(S, A)",
"Caden(a",
"Caden(.A))",
"Caden.Q",
"Caden.K",
"Caden"
]

data = {'People' : ["Caden(S, A) Charlotte.A, Caden.K;", "Emily.P Ethan.B; Caden(a", "Grayson.Q, Lily; Caden(.A))", "Mason, Emily.Q Noah.B; Caden.Q - Riley.P"]}

df = pd.DataFrame(data)

pat = '|'.join(r"\b{}\b".format(x) for x in Keywords)

df["found"] = df['People'].str.findall(pat).str.join('; ')

print df["found"]

它返回楠。我想挑战在于关键字中的空格和括号。

获得理想输出的正确方法是什么?谢谢。

Caden(S, A); Caden.K
Caden(a
Caden(.A))
Caden.Q

【问题讨论】:

  • pat = r'(?<!\w)(?:{})(?!\w)'.format('|'.join(map(re.escape, sorted(Keywords,key=len,reverse=True))))?我不确定它是否会起作用,因为您似乎需要列出所有值。如果有W1W1 W2,则只会返回W1 W2
  • 好的,让我们删除 cmets。请修正问题中的逗号。

标签: python regex pandas dataframe


【解决方案1】:

由于您不需要找到 every 关键字,但最长的关键字如果重叠,您可以使用带有findall 方法的正则表达式。

这里的重点是你需要先把关键词按长度降序排列(因为里面有空格),然后你需要对这些值进行转义,因为它们包含特殊字符,然后你必须修改单词边界使用明确字边界,(?<!\w)(?!\w)(请注意,\b 取决于上下文)。

使用

pat = r'(?<!\w)(?:{})(?!\w)'.format('|'.join(map(re.escape, sorted(Keywords,key=len,reverse=True))))

查看online Python test

import re
Keywords = ["Caden(S, A)", "Caden(a","Caden(.A))", "Caden.Q", "Caden.K", "Caden"]
rx = r'(?<!\w)(?:{})(?!\w)'.format('|'.join(map(re.escape, sorted(Keywords,key=len,reverse=True))))
# => (?<!\w)(?:Caden\(S,\ A\)|Caden\(\.A\)\)|Caden\(a|Caden\.Q|Caden\.K|Caden)(?!\w)
strs = ["Caden(S, A) Charlotte.A, Caden.K;", "Emily.P Ethan.B; Caden(a", "Grayson.Q, Lily; Caden(.A))", "Mason, Emily.Q Noah.B; Caden.Q - Riley.P"]
for s in strs:
    print(re.findall(rx, s))

输出

['Caden(S, A)', 'Caden.K']
['Caden(a']
['Caden(.A))']
['Caden.Q']

【讨论】:

    【解决方案2】:

    嘿,不知道这个解决方案是否最佳,但它有效。我只是用 8 和 '(' 用 6 和 ')' 用 9 替换 dot 不知道为什么这些字符会被 str.findall 忽略?

    {8,6,9} 和 {'.','(',')'} 之间的一种双射

    for i in range(len(Keywords)): 
        Keywords[i] = Keywords[i].replace('(','6').replace(')','9').replace('.','8')
    for i in range(len(df['People'])): 
        df['People'][i] = df['People'][i].replace('(','6').replace(')','9').replace('.','8')
    

    然后你应用你的函数

      pat = '|'.join(r"\b{}\b".format(x) for x in Keywords)
      df["found"] = df['People'].str.findall(pat).str.join('; ')
    

    最后一步取回 {'.','(',')'}

    for i in range(len(df['found'])): 
      df['found'][i] = df['found'][i].replace('6','(').replace('9',')').replace('8','.')
      df['People'][i] = df['People'][i].replace('6','(').replace('9',')').replace('8','.')
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2019-02-16
      • 2021-12-01
      • 1970-01-01
      • 2014-09-19
      • 1970-01-01
      • 2019-01-05
      • 1970-01-01
      相关资源
      最近更新 更多