python中的高效字频数用于单台机器中的大规模处理

时间:2015-07-06 21:06:06

标签: python word-frequency

我有一个包含字符串内容的大文本文件。我的用例是识别单词及其相应的计数。

在python中,实现此目的的一种常用方法是使用字典并跟踪单词及其计数。还有另一种方法可以使用收藏计数器找出最常见的单词。

上述方法工作正常,但由于dict的大小将是唯一字的总数,因此它不具有空间效率。 有没有其他有效的算法来找出单个机器中大数据的单词基数?即不使用分布式计算,如Hadoop Map reduce或Spark?

2 个答案:

答案 0 :(得分:1)

修改的标记化方法有可能产生多字标记,这很容易导致字典大小远大于10 ** 6。 由于请求的解决方案似乎只涉及将所有令牌存储在内存中,因此基于Trie的存储而不是dict可能就足够了。

查看显示

hat-trie
  

对于共享前缀的密钥,它通常比Python使用更少的内存   字典。

虽然会有一些牺牲速度。其他此类数据结构包括datrie,marisa-trie和DAWG。

您可以进行多重处理以加快计数速度。

答案 1 :(得分:0)

好吧,我不认为你可以通过这种方式存储唯一单词的总数。正如你所提到的,collections.Counter可能是最简单的方法。

如果内存使用有问题,您可以尝试将结果存储在numpy数组中,尽管对于这种特殊情况它不是非常合适/最佳。

同样,无论数据集有多大,都只有10**6 unique words in English(可能只有10%被积极使用),所以假设每个单词的平均长度为10个字符,每个字符为1个字节,相应的内存大小在C中只有~10 MB,并且说可能是~100MB占Python开销和unicode。实际上,生成一个带有10 ** 6个随机10个字符长字的字典,需要115 MB,因此在任何现代系统中存储都不应该存在问题。

In [14]: import string
    ...: import random
    ...: import itertools
    ...: %load_ext memory_profiler
    ...:
    ...: def gen_dict(n):
    ...:     out = {}
    ...:     for i, name in enumerate(itertools.product(string.letters, repeat=10)):
    ...:         if i > n: break
    ...:         out[''.join(name)] = random.randint(0, N)
    ...:     return out
    ...:
    ...: N = 1000000
    ...: %memit x = gen_dict(N)
    ...: print(len(x.keys()))
    ...: 
peak memory: 150.45 MiB, increment: 116.52 MiB
1000001