【问题标题】:How to get word frequency using collections.Counter, even when the count is zero?即使计数为零,如何使用 collections.Counter 获取词频?
【发布时间】:2016-06-05 09:28:46
【问题描述】:

我正在尝试获取目录中多个文件中出现的单词频率的计数,并且感谢here这个答案,我能够获得单词出现时间的结果。但是,当单词出现 0 次时,我不知道如何也显示结果。

例如 这是我想要的结果,所以我总是得到所有指定单词的结果,第一行是指定单词,下面是计数。

21, 23, 60 4, 0, 8

这是我当前的代码:

import csv
import copy
import os
import sys
import glob
import string
import fileinput
from collections import Counter

def word_frequency(fileobj, words):
    """Build a Counter of specified words in fileobj"""
    # initialise the counter to 0 for each word
    ct = Counter(dict((w, 0) for w in words))
    file_words = (word for line in fileobj for word in line.split())
    filtered_words = (word for word in file_words if word in words)
    return Counter(filtered_words)


def count_words_in_dir(dirpath, words, action):
    """For each .txt file in a dir, count the specified words"""
        for filepath in glob.iglob(os.path.join(dirpath, '*.txt_out')):
            filepath = {}
        with open(filepath) as f:
            ct = word_frequency(f, words)
            action(filepath, ct)


def final_summary(filepath, ct):
    words = sorted(ct.keys())
    counts = [str(ct[k]) for k in words]
    with open('new.csv','a') as f:
        [f.write('{0},{1}\n,{2}\n'.format(
            filepath,
        ', '.join(words),
        ', '.join(counts)))]


words = set(['21','23','60','75','79','86','107','121','147','193','194','197','198','199','200','201','229','241','263','267','309','328'])
count_words_in_dir('C:\\Users\jllevent\Documents\PE Submsissions\Post-CLI', words, action=final_summary)

【问题讨论】:

  • 一些附加说明:您可以通过让dict.fromkeys 为您完成工作来节省一些初始化ct 的工作:ct = Counter(dict.fromkeys(words, 0))。您可以通过使用带有 C 内置函数的内置函数以其他方式将更多工作推送到 C 层,例如file_words = itertools.chain.from_iterable(map(str.split, fileobj))filtered_words = filter(frozenset(words).__contains__, file_words),然后是 Counter.update(filtered_words)(虽然 Counter.update 是用 Python 实现的,但现代 Python 中的繁重工作是由 C 加速的 collections._count_elements 完成的)。
  • 注意:mapfilter 应该是 Python 3 版本,以在没有大量浪费临时对象的情况下获得最佳性能;在 Python 2 中,您可以使用 from future_builtins import map, filter 来获取这些函数的基于生成器的版本。此外,如果您使用的是 Python 2.7/3.1 或更高版本,则可以使用 set 文字而不是包装在 set 构造函数中的 list 文字:word = {'21','23','60','75','79','86','107','121','147','193','194','197','198','199','200','201','229','241','263','267','309','328'}

标签: python counter


【解决方案1】:

你从来没有使用你在word_frequency中构造的ct计数器,而是构造一个只有现有单词的新计数器,你需要使用你构造的ct,例如:

...
for word in file_words:
    if word in words:
        ct[word] += 1
return ct

或者正如下面@ShadowRanger 指出的那样:

ct.update(word for word in file_words if word in words)
return ct

【讨论】:

  • 这样就完成了!非常感谢:)
  • Counter 有一个 update 方法可以显着简化(并加快速度):ct.update(word for word in file_words if word in words)
【解决方案2】:

如果单词没有出现,它看起来会返回 NULL。放入条件返回语句,如果它返回的值不是 int > 0,则返回 0。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-08-25
    • 2017-11-20
    • 1970-01-01
    • 1970-01-01
    • 2021-09-11
    • 2021-01-07
    相关资源
    最近更新 更多