【问题标题】:Checking if any word in a string appears in a list using python使用python检查字符串中的任何单词是否出现在列表中
【发布时间】:2020-08-26 20:36:05
【问题描述】:

我有一个包含数千个 cmets 的列的 pandas 数据框。我想遍历列中的每一行,检查评论是否包含在我创建的单词列表中找到的任何单词,如果评论包含我列表中的单词,我想将其标记为一个单独的列。到目前为止,这是我的代码中的内容:

retirement_words_list = ['match','matching','401k','retirement','retire','rsu','rrsp']

def word_checker(row):
    for sentence in df['comments']: 
        if any(word in re.findall(r'\w+', sentence.lower()) for word in retirement_words_list):
            return '401k/Retirement'
        else:
            return 'Other'

df['topic'] = df.apply(word_checker,axis=1)    

即使我已经仔细检查了许多 cmets 是否包含我列表中的一个或多个单词,代码也会将我的数据框中的每条评论都标记为“其他”。关于如何更正我的代码的任何想法?非常感谢您的帮助。

【问题讨论】:

  • 类似于这里的第一个选项:stackoverflow.com/questions/61390726/…?只需将case=False 指定为str.contains 的参数
  • retirement_words_list 更改为一个集合可能会加快查找速度。测试列表中的成员身份是 O(n),而测试集合中的成员身份是 O(1) - 详细信息:wiki.python.org/moin/TimeComplexity
  • @jsmart 这取决于它的使用方式。目前代码没有使用retirement_words_list进行包含测试,仅用于迭代。

标签: python pandas dataframe if-statement any


【解决方案1】:

拥有retirements_word_list 的集合版本可能更方便(用于有效的包含测试)然后循环句子中的单词,检查是否包含在这个集合中,而不是反过来:

retirement_words_list = ['match','matching','401k','retirement','retire','rsu','rrsp']

retirement_words_set = set(retirement_words_list)

然后

    if any(word in retirement_words_list for word in sentence.lower().split()):
            # .... etc ....

您的代码只是检查retirement_words_list 中的任何单词是否是句子的子字符串,但实际上您必须查找整个单词匹配,否则包含'matching''retirement' 没有意义鉴于'match''retire' 已包含在列表中。因此使用split -- 以及我们也可以反转逻辑的原因。

注意:您可能需要进行一些进一步的更改,因为您的函数word_checker 有一个名为row 的参数,它不使用它。你的意思可能是这样的:

def word_checker(sentence):
    if any(word in retirement_words_list for word in sentence.lower().split()):
        return '401k/Retirement'
    else:
        return 'Other'

和:

df['topic'] = df['comments'].apply(word_checker,axis=1)    

其中sentencecomments 列中每一行的内容。

【讨论】:

  • 非常感谢阿拉尼。猜猜我的方法有点倒退,没有完全充实。在发布之前,我花了很长时间尝试自己解决此问题。感谢您花时间回答!
【解决方案2】:

这个简化版本(没有正则表达式)不工作吗?

if any(word in sentence.lower() for word in retirement_words_list):

【讨论】:

  • 嗨拉斐尔。谢谢回复。不幸的是,使用您建议的简化版本会产生相同的结果。我也试过做 sentence.lower.split() 并得到相同的结果。
  • 有趣,我尝试了一些转储语句,它奏效了。也许你的句子是不同的形式?你能检查一下sentence 是什么,是你期望的吗?
  • 这是一个很好的观点。我检查以确保该列中的值是我预期的字符串格式。实际上,我尝试按照 ALloz 包含的链接中使用的方法,这似乎已经成功了。非常感谢 Rafael 抽出宝贵时间回答!
猜你喜欢
  • 1970-01-01
  • 2011-07-16
  • 1970-01-01
  • 1970-01-01
  • 2017-02-28
  • 1970-01-01
  • 2015-05-31
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多