【问题标题】:search keywords in dataframe cell在数据框单元格中搜索关键字
【发布时间】:2019-11-07 04:29:35
【问题描述】:

我目前有一个包含一些单词或字符的列的数据框,我试图通过相应单元格中的搜索关键字对每一行进行分类。

例子

  words             |   category
-----------------------------------
im a test email     |  email
here is my handout  |  handout

这就是我所拥有的

conditions = [
        (df['words'].str.contains('flyer',False,regex=True)),
        (df['words'].str.contains('report',False,regex=True)),
        (df['words'].str.contains('form',False,regex=True)), 
        (df['words'].str.contains('scotia',False,regex=True)),  
        (df['words'].str.contains('news',False,regex=True)), 
         (df_prt_copy['words'].str.contains('questions.*\.pdf',False,regex=True)),
         .
         .
         .
         .
    ]
    choices = ['open house flyer', 
               'report', 
               'form', 
               'report',
               'news', 
               ‘question',
                  .
                  .
                  .
                  .
              ]
     df['category']=np.select(conditions, choices, default='others')

这很好用,但问题是我有很多关键字(可能超过 120 个左右),所以维护这个关键字列表非常困难,有没有更好的方法来做到这一点? 顺便说一句,我正在使用 python3

注意:我正在寻找一种更简单的方法来管理大量关键字,这与简单的查找关键字的方法不同here

【问题讨论】:

标签: python python-3.x pandas numpy


【解决方案1】:

如果一行中有多个关键字,您可以加入所有关键字并使用 str.findall,然后将 map 用于 cond 与选择的字典:

df = pd.DataFrame({"words":["im a test email",
                            "here is my handout",
                            "This is a flyer"]})

choices = {"flyer":"open house flyer",
           "email":"email from someone",
           "handout":"some handout"}

df["category"] = df["words"].str.findall("|".join(choices.keys())).str.join(",").map(choices)

print (df)

#
                words            category
0     im a test email  email from someone
1  here is my handout        some handout
2     This is a flyer    open house flyer

【讨论】:

  • 这可以用字典来完成吗?将它们放在一起时,我无法匹配关键字和相应类别的顺序,因为它们太多了
  • 我今天会测试它并回到这里,谢谢@Henry Yik
  • 嵌入了一些词,例如“todayIgotAemailReport”,这不返回“email”类别,我想这个方法不适用正则表达式,有什么办法吗?
  • 为什么不返回邮件类别?
  • 我猜今天 IgotAemailReport 是一个与单词“email”不匹配的单词,我原来的方法启用了正则表达式,所以这不是问题
【解决方案2】:

你可以使用 flashtext..

 import pandas as pd
 from flashtext import KeywordProcessor

 keyword_dict = {
 'programming': ['python', 'pandas','java','java_football'],
 'sport': ['cricket','football','baseball']
 } 

 kp = KeywordProcessor()
 kp.add_keywords_from_dict(keyword_dict)
 df = pd.DataFrame(['i love working in python','pandas is very popular library','i love playing football'],columns= ['text'])

 df['category'] = df['text'].apply(lambda x: kp.extract_keywords(x, span_info = True))

现在遇到像“todayIgotAemailReport”这样的词的问题,您可以参考 How to split text without spaces into list of words? 认为这可能有助于您拆分任何类型的未知连接词

import wordninja
' '.join(wordninja.split('todayIgotAemailReport'))

#this will break this into their respective word which can make your stuff easy, while searching
#op
'today I got A email Report' 

【讨论】:

  • 试过这个方法,但是java_footbal没有被识别
  • 还有一件事,这个方法只能找到第一个匹配,对吧?
  • 另外,我注意到 flashtext 似乎更快,但有没有办法用正则表达式来做到这一点?现在,当我测试时,“todayIgotAemailReport”没有被识别为电子邮件类别
  • 不,它会给你所有匹配,kp.extract_keywords(x) 这个给定列表,我选择了索引为零的项目,这就是为什么当没有找到关键字时它会抛出错误,因为列表是空的
  • @ikel 我已经修改了代码,包括 span_info = True ,这样你就可以得到找到的单词的位置
【解决方案3】:

您可以动态创建conditions 列表。如果你有一个关键字列表,比如key_words,你可以for 循环遍历关键字列表,然后append 条件如(df['words'].str.contains(key_words[iter], False, regex=True)) 到列表conditions

【讨论】:

  • 在这种情况下,我仍然必须匹配“选择”列表中的序列,并且该列表应该像一个类别列表,我希望有某种方法可以使用 dict 来替换那些'选择”和“条件”列表
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-05-03
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多