首页 > 解决方案 > 附加多个 Counter() 对象并转换为数据框

问题描述

我想在多个 .txt 文件中查找保留字列表的词频作为熊猫数据框。我正在使用 collections.Counter() 对象,如果某个单词没有出现在文本中,则 Counter() 中该单词(键)的值为零。

理想情况下,结果是一个数据框,其中每一行对应于每个 .txt 文件,列标题对应于保留字,第 i 行第 j 列中的条目对应于第 i 个 .txt 中第 j 个单词的频率文件。

这是我的代码,但问题是 Counter() 对象没有附加,在字典的意义上,每个键(或保留字)都有多个值,而是相加:

for filepath in iglob(os.path.join(folder_path, '*.txt')):
    with open(filepath) as file:
        cnt = Counter()
        tokens = re.findall(r'\w+', file.read().lower())
        for word in tokens:
            if word in mylist:
                cnt[word] += 1
            for key in mylist:
                if key not in cnt:
                    cnt[key] = 0
        dictionary = defaultdict(list)
        for key, value in cnt.items():
            dictionary[key].append(value)
    print(dictionary)

任何提示将不胜感激!

标签: pythonpython-3.xword-frequency

解决方案


您需要在循环之前为数据框创建字典,然后复制/附加Counter每个文本文件的值。

#!/usr/bin/env python3
import os
import re
from collections import Counter
from glob import iglob


def main():
    folder_path = '...'
    keywords = ['spam', 'ham', 'parrot']

    keyword2counts = {keyword: list() for keyword in keywords}
    for filename in iglob(os.path.join(folder_path, '*.txt')):
        with open(filename) as file:
            words = re.findall(r'\w+', file.read().lower())

        keyword2count = Counter(word for word in words if word in keywords)

        for keyword in keywords:
            keyword2counts[keyword].append(keyword2count[keyword])

    print(keyword2counts)


if __name__ == '__main__':
    main()

测试 a 中的项目是否list比对 a 中的项目进行相同的测试要慢得多set。因此,如果这太慢,您可能会使用setforkeywords或额外的仅用于测试。

如果collections.OrderedDict列的顺序相关,则在 Python 3.7(或 CPython 3.6)之前。


推荐阅读