python-3.x - 如何在 pandas df 中计算标记化句子中的特定术语
问题描述
我是 Python 和 nltk 的新手,因此非常感谢您对以下问题的意见。
目标:
我想搜索并计算存储在 pandas DataFrame 中的标记化句子中特定术语的出现。我正在搜索的术语存储在字符串列表中。输出应保存在新列中。
由于我要搜索的单词在语法上是变形的(例如 cat 而不是 cat),因此我需要一个不仅显示完全匹配的解决方案。我想对数据进行词干化并搜索特定词干将是一种合适的方法,但我们假设这不是一个选项,因为我们仍然会有语义重叠。
到目前为止我尝试了什么:
为了进一步处理数据,我在执行以下步骤时对数据进行了预处理:
- 把所有东西都小写
- 删除标点符号
- 代币化
- 删除停用词
我尝试搜索单个术语,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
解决方案
一个非常简单的解决方案是:
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)
推荐阅读
- mysql - 我正在尝试在 sql 中运行查询,在其中将字段更改为小写以使其一致并对不同字段求和
- javascript - 使用 Vue 进行 Firestore 分页
- java - 双击 .jar 文件时程序无法正常运行
- javascript - Javascript Map 函数是异步的吗?
- html - 即使在滚动时,也使侧边栏(在 React 中)占据页面高度的 100%
- regex - 相同的模式 Apper 多个时间捕获全部使用 gawk
- php - 提交前填充的 PHP `POST`
- angular - 服务变量和数据的角度变化检测
- r - 使用 Tukey 检验校正效果
- javascript - 如何在基本 html 模板中使用 {% load staticfiles%} 导入 js 文件