我有一个包含字符串内容的大文本文件。我的用例是识别单词及其相应的计数。
在python中,实现此目的的一种常用方法是使用字典并跟踪单词及其计数。还有另一种方法可以使用收藏计数器找出最常见的单词。
上述方法工作正常,但由于dict的大小将是唯一字的总数,因此它不具有空间效率。 有没有其他有效的算法来找出单个机器中大数据的单词基数?即不使用分布式计算,如Hadoop Map reduce或Spark?
答案 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