python - 通过在 Python 3.7 中按段落计算单词来自定义数据结构

标签 python python-3.x string data-structures

我有一个要求来完成以下任务:

  • 对于给定的单词或标记,确定它出现在多少个段落中(称为文档频率)
  • 创建一个数据结构(dict、pandas dataframe 等),其中包含单词、它的收集(总体)频率和文档频率

示例数据集如下所示:

<P ID=1>
I have always wanted to try like, multiple? Different rasteraunts. Not quite sure which kind, maybe burgers!
</P>

<P ID=2>
Nice! I love burgers. Cheeseburgers, too. Have you ever gone to a diner type restauraunt? I have always wanted to try every diner in the country.
</P>

<P ID=3>
I am not related to the rest of these paragraphs at all.
</P>

“段落”由 <P ID=x> </P> tags 的存在定义

我需要的是创建一个看起来有点像这样的数据结构(我想它是一个 dict ):

{'i': X Y, 'have': X Y, etc}

或者,可能是 pandas看起来像这样的数据框:

| Word | Content Frequency | Document Frequency |
|   i  |         4         |          3         |
| have |         3         |          2         |
| etc  |         etc       |          etc       |

目前,我可以使用以下代码毫无问题地找到内容频率。

import nltk
import string
from nltk.tokenize import word_tokenize, RegexpTokenizer
import csv
import numpy
import operator
import re

# Requisite
def get_input(filepath):
    f = open(filepath, 'r')
    content = f.read()
    return content

# 1
def normalize_text(file):
    file = re.sub('<P ID=(\d+)>', '', file)
    file = re.sub('</P>', '', file)
    tokenizer = RegexpTokenizer(r'\w+')
    all_words = tokenizer.tokenize(file)
    lower_case = []
    for word in all_words:
        curr = word.lower()
        lower_case.append(curr)

    return lower_case

# Requisite for 3
# Answer for 4
def get_collection_frequency(a):
    g = {}
    for i in a:
        if i in g: 
            g[i] +=1
        else: 
            g[i] =1
    return g

myfile = get_input('example.txt')
words = normalize_text(myfile)

## ANSWERS
collection_frequency = get_collection_frequency(words)
print("Collection frequency: ", collection_frequency)

返回:

Collection frequency:  {'i': 4, 'have': 3, 'always': 2, 'wanted': 2, 
'to': 4, 'try': 2, 'like': 1, 'multiple': 1, 'different': 1,
'rasteraunts': 1, 'not': 2, 'quite': 1, 'sure': 1, 'which': 1,
'kind': 1, 'maybe': 1, 'burgers': 2, 'nice': 1, 'love': 1,
'cheeseburgers': 1, 'too': 1, 'you': 1, 'ever': 1, 'gone': 1, 'a': 1,
'diner': 2, 'type': 1, 'restauraunt': 1, 'every': 1, 'in': 1, 'the': 2,
'country': 1, 'am': 1, 'related': 1, 'rest': 1, 'of': 1, 'these': 1, 
'paragraphs': 1, 'at': 1, 'all': 1}

但是,我目前正在删除 normalize_text 中某个段落的“标题”函数与行:

file = re.sub('<P ID=(\d+)>', '', file)
file = re.sub('</P>', '', file)

因为我不想P , ID , 1 , 2 , 3算在我的字典里,因为那些只是段落标题。

那么我怎样才能将一个词的出现与它在段落中的实例联系起来,从而产生上述期望的结果?我什至不确定尝试创建这样一个数据结构的逻辑。

最佳答案

How then can I tie the occurrence of a word back to its instance in a paragraph that would yield me the desired results above?

将过程分为两部分:查找段落和查找单词

from nltk.tokenize import RegexpTokenizer
import re, collections

p = r'<P ID=\d+>(.*?)</P>'
paras = RegexpTokenizer(p)
words = RegexpTokenizer(r'\w+')

解析时保留两本字典:一本用于收集频率,一本用于文档频率。

col_freq = collections.Counter()
doc_freq = collections.Counter()

遍历段落;获取段落中的单词;将单词提供给 col_freq 字典,并将一组单词提供给 doc_freq 字典

for para in paras.tokenize(text):
    tokens = [word.lower() for word in words.tokenize(para)]
    col_freq.update(tokens)
    doc_freq.update(set(tokens))

合并两个词典。

d = {word:(col_freq[word], doc_freq[word]) for word in col_freq}

那里有一些低效 - 两次解析文本 - 但如果它成为问题,可以对其进行调整。

RegexpTokenizer在这种情况下,实际上除了 re.findall() 之外什么也没做,但它隐藏了一些细节并使它不那么冗长,所以我使用了它。


有时 re 不能很好地处理格式错误的标记。可以使用 BeautifulSoup 来解析段落。

from bs4 import BeautifulSoup
soup = BeautifulSoup(text,"html.parser")
for para in soup.find_all('p'):
    tokens = [word.lower() for word in words.tokenize(para.text)]
    print(tokens)
##    col_freq.update(tokens)
##    doc_freq.update(set(tokens))

关于python - 通过在 Python 3.7 中按段落计算单词来自定义数据结构,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57763511/

相关文章:

java - 需要有关 Java 字符串的帮助

python - 比较字典中的键和值,并将不匹配的值输出到列表中

python - 没有内存上传 - python-requests 无法使用流文件

python - 当参数具有相同的名称时如何恢复内置?

python - 导入错误 : No module named pip after trying to upgrade pip

string - 如何复制 String 或 str

python - 在 Python 中使用 cx_freeze 时,未添加 VCRUNTIME140.DLL

Python 3.5 Pyperclip 模块导入失败

python-3.x - Microsoft Azure Spark kusto 连接器 - 是否可以从 databricks 中获取 azure 存储的文件?

string - 从字符串转换时如何确定 []rune 的容量