【问题标题】:Creation of custom data structure by combining list and dict- Python 3.x通过组合列表和字典创建自定义数据结构 - Python 3.x
【发布时间】:2020-01-17 09:59:15
【问题描述】:

我需要扫描一个文本文件,扫描后需要完成以下操作:

  • 确定文件中的“文档”(可通过​​<P ID=xxx></P> 标签确定)
  • 对于每个文档,确定出现了哪些单词以及出现了多少次
  • 然后,创建一个整体字典,其中键是一个单词,它的第一个值是它出现的文档总数,它的第二个(和后续)值是文档的元组对,以及它在该文档中的出现

文件示例如下所示:

<P ID=1>
Lorem ipsum dolor sit amet
</P>

<P ID=2>
consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. 
</P>

<P ID=3>
Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur.
</P>

<P ID=4>
Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
</P>

<P ID=5>
654654
</P>

目前,我可以完成前两个要求,以及第二个要求的一部分。我的代码目前能够生成一个单词出现多少个“文档”(由标签的存在定义),以及对于每个文档,哪些单词出现了多少次。

我的程序如下:

import nltk
from nltk.tokenize import word_tokenize, RegexpTokenizer
from nltk.corpus import stopwords
import csv
import operator
import re
import pandas
import collections
from collections import defaultdict, Counter
import sys

def remove_nums(arr): 
    pattern = '[0-9]'
    arr = [re.sub(pattern, '', i) for i in arr] 
    return arr



# Main Program
def main():
    myfile = get_input("path")

    stop_words = list(stopwords.words('english'))
    p = r'<P ID=\d+>(.*?)</P>'
    paras = RegexpTokenizer(p)
    num_paragraphs = len(paras.tokenize(myfile))

    currTokens = []
    currFrequency = collections.Counter()
    #currFrequencies = []
    currID = []
    id_num = 1
    words = RegexpTokenizer(r'\w+')

    document_frequency = collections.Counter()
    for para in paras.tokenize(myfile):
        lower = [word.lower() for word in words.tokenize(para)]
        no_integers = remove_nums(lower)
        dirty_tokens = [data for data in no_integers if data not in stop_words]
        tokens = [data for data in dirty_tokens if data.strip()]
        document_frequency.update(set(tokens))

    for para in paras.tokenize(myfile):
        lower = [word.lower() for word in words.tokenize(para)]
        no_integers = remove_nums(lower)
        dirty_tokens = [data for data in no_integers if data not in stop_words]
        tokens = [data for data in dirty_tokens if data.strip()]
        currFrequencies = collections.Counter(tokens)
        print(id_num, " - ", currFrequencies)
        id_num += 1

    print()
    print(document_frequency)

产生:

1  -  Counter({'lorem': 1, 'ipsum': 1, 'dolor': 1, 'sit': 1, 'amet': 1})
2  -  Counter({'ut': 3, 'consectetur': 1, 'adipiscing': 1, 'elit': 1, 'sed': 1, 'eiusmod': 1, 'tempor': 1, 'incididunt': 1, 'labore': 1, 'et': 1, 'dolore': 1, 'magna': 1, 'aliqua': 1, 'enim': 1, 'ad': 1, 'minim': 1, 'veniam': 1, 'quis': 1, 'nostrud': 1, 'exercitation': 1, 'ullamco':
1, 'laboris': 1, 'nisi': 1, 'aliquip': 1, 'ex': 1, 'ea': 1, 'commodo': 1, 'consequat': 1})
3  -  Counter({'duis': 1, 'aute': 1, 'irure': 1, 'dolor': 1, 'reprehenderit': 1, 'voluptate': 1, 'velit': 1, 'esse': 1, 'cillum': 1, 'dolore': 1, 'eu': 1, 'fugiat': 1, 'nulla': 1, 'pariatur': 1})
4  -  Counter({'excepteur': 1, 'sint': 1, 'occaecat': 1, 'cupidatat': 1, 'non': 1, 'proident': 1, 'sunt': 1, 'culpa': 1, 'qui': 1, 'officia':
1, 'deserunt': 1, 'mollit': 1, 'anim': 1, 'id': 1, 'est': 1, 'laborum': 1})
5  -  Counter()

Counter({'dolor': 2, 'dolore': 2, 'lorem': 1, 'ipsum': 1, 'amet': 1, 'sit': 1, 'sed': 1, 'incididunt': 1, 'tempor': 1, 'labore': 1, 'laboris': 1, 'aliqua': 1, 'veniam': 1, 'quis': 1, 'consequat': 1, 'adipiscing': 1, 'ea': 1, 'nostrud': 1, 'consectetur': 1, 'aliquip': 1, 'ad': 1, 'enim': 1, 'elit': 1, 'eiusmod': 1, 'commodo': 1, 'ut': 1, 'ex': 1, 'ullamco': 1, 'nisi': 1, 'minim': 1, 'exercitation': 1, 'et': 1, 'magna': 1, 'fugiat': 1, 'eu': 1, 'duis': 1, 'reprehenderit': 1, 'voluptate': 1, 'pariatur': 1, 'irure': 1, 'esse': 1, 'nulla': 1, 'aute': 1, 'velit': 1, 'cillum': 1, 'mollit': 1, 'excepteur': 1, 'non': 1, 'cupidatat': 1, 'laborum': 1, 'anim': 1, 'est': 1, 'officia': 1, 'deserunt': 1, 'sunt': 1,
'occaecat': 1, 'culpa': 1, 'id': 1, 'proident': 1, 'qui': 1, 'sint': 1})

但是,我需要一个字典形式的数据结构:

word: document_frequency, (paragraph, count of appearances), (paragraph, count of appearances), (paragraph, count of appearances), etc.

例如:

{dolor: 2, (1, 1), (2, 0), (3, 1), (4, 0), (5, 0)}

如何组合我的收集频率以达到上述预期结果?

【问题讨论】:

  • 我会创建一个set,其中包含所有段落中的所有单词,然后遍历单词,不断建立总计数并提取每个段落的计数。
  • 我可以看到不断添加到tokens,然后将其转换为set,但您的评论building the total count as you go and pulling out the per-paragraph count. 是我不知道该怎么做的事情。也许你可以展示一下?

标签: python python-3.x dictionary data-structures collections


【解决方案1】:

类似于下面的伪代码

words = set(all the words from all the counters)
d = {}
for word in words:
    para_counts = [0]  # This will end up as [2, (1, 1), (2, 0) ...]
    for i, para in enumerate(paras, 1):  # 1-indexed
        para_count = para[word]
        para_counts[0] += para_count  # Update the all-paras word total
        para_counts.append((i, para_count))  # Add the this-para (1, 1) tuple
    d[word] = para_counts

【讨论】:

  • all the words from all the counters - 这只是一组单独的令牌,例如:[lorem, ipsum, tom, dalton] 还是您的意思是计数?
  • `字符串索引必须是整数
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-05-31
  • 2021-04-03
  • 1970-01-01
  • 2015-09-30
  • 2011-05-25
相关资源
最近更新 更多