首页 > 解决方案 > 如何在 pandas df 中计算标记化句子中的特定术语

问题描述

我是 Python 和 nltk 的新手,因此非常感谢您对以下问题的意见。

目标:

我想搜索并计算存储在 pandas DataFrame 中的标记化句子中特定术语的出现。我正在搜索的术语存储在字符串列表中。输出应保存在新列中。

由于我要搜索的单词在语法上是变形的(例如 cat 而不是 cat),因此我需要一个不仅显示完全匹配的解决方案。我想对数据进行词干化并搜索特定词干将是一种合适的方法,但我们假设这不是一个选项,因为我们仍然会有语义重叠。

到目前为止我尝试了什么:

为了进一步处理数据,我在执行以下步骤时对数据进行了预处理:

  1. 把所有东西都小写
  2. 删除标点符号
  3. 代币化
  4. 删除停用词

我尝试搜索单个术语,str.count('cat')但这并不能解决问题,并且数据被标记为丢失NaN。此外,我不知道如何在使用 pandas 时以有效的方式迭代搜索词列表。

到目前为止我的代码:

import numpy as np
import pandas as pd
import re
from nltk.tokenize import word_tokenize
from nltk.corpus import stopwords

# Function to remove punctuation
def remove_punctuation(text):
    return re.sub(r'[^\w\s]','',text)


# Target data where strings should be searched and counted
data = {'txt_body': ['Ab likes dogs.', 'Bc likes cats.',
                     'De likes cats and dogs.', 'Fg likes cats, dogs and cows.',
                     'Hi has two grey cats, a brown cat and two dogs.']}


df = pd.DataFrame(data=data)

# Search words stored in a list of strings
search_words = ['dog', 'cat', 'cow']

# Store stopwords from nltk.corpus
stop_words = set(stopwords.words('english'))

# Data preprocessing
df['txt_body'] = df['txt_body'].apply(lambda x: x.lower())
df['txt_body'] = df['txt_body'].apply(remove_punctuation)
df['txt_body'] = df['txt_body'].fillna("").map(word_tokenize)
df['txt_body'] = df['txt_body'].apply(lambda x: [word for word in x if word not in stop_words])

# Here is the problem space
df['search_count'] = df['txt_body'].str.count('cat')



print(df.head())

预期输出:

                                       txt_body  search_count
0                             [ab, likes, dogs]             1
1                             [bc, likes, cats]             1
2                       [de, likes, cats, dogs]             2
3                 [fg, likes, cats, dogs, cows]             3
4  [hi, two, grey, cats, brown, cat, two, dogs]             3

标签: python-3.xpandasnlpnltk

解决方案


一个非常简单的解决方案是:

def count_occurence(l, s):
    counter = 0
    for item in l:
        if s in item:
            counter += 1
    return counter

df['search_count'] = df.apply(lambda row: count_occurence(row.txt_body, 'cat'),1)

然后您可以进一步决定如何定义 count_occurence 函数。而且,要搜索整个 search_words,这样的事情就可以完成,尽管它可能不是最有效的:

def count_search_words(l, search_words):
    counter = 0
    for s in search_words:
        counter += count_occurence(l, s)
    return counter

df['search_count'] = df.apply(lambda row: count_search_words(row.txt_body, search_words),1)  

推荐阅读