计数器元组键拆分的内存节省替代方案

Memory saving alternatives to Counter tuple keys splitting

输入是一个字符串元组列表,我需要

个计数

我目前是这样做的:

>>> from collections import Counter
>>> data = [('foo','bar'), ('foo', 'bar'), ('foo', 'doo'), ('joo', 'doo'), ('koo', 'lar')]
>>> datacount = Counter(data)
>>> datacount
Counter({('foo', 'bar'): 2, ('joo', 'doo'): 1, ('koo', 'lar'): 1, ('foo', 'doo'): 1})
>>> x, y = zip(*datacount.keys())
>>> x
('joo', 'foo', 'koo', 'foo')
>>> y
('doo', 'bar', 'lar', 'doo')
>>> xcount = Counter(x)
>>> ycount = Counter(y)
>>> xcount
Counter({'foo': 2, 'koo': 1, 'joo': 1})
>>> ycount
Counter({'doo': 2, 'bar': 1, 'lar': 1})

但我意识到它占用了三个独立的计数器。 除了获取计数和其他我可以轻松获取计数的数据结构之外,还有其他方法吗?

如果您想保留 X、Y 和 X*Y 的预计算计数,则没有办法为每个可能的 X、Y 和 X*Y 保留一个值,您当前的解决方案与任何解决方案一样好。

如果您正在使用 3 个单独的 Counter 对象这一事实让您感到困扰,您可以将所有计数保存在一个 Counter 中,尽管它不会减少内存使用。

如果不需要预先计算所有内容并将其加载到内存中,您可以:

  • 保留 'pointers' 而不是对象 - 如果实际的字符串非常大并且您想避免将它们加载到内存中,您可以为每个字符串分配一个 id,保留 id 的计数,并仅在必要时映射回字符串。
  • Lazy loading/counting - 您可以维护每个字符串到它在磁盘上出现的元组的映射,并通过仅加载相关元组来按需计算计数,即:

def count(x,y):
    X = load_tuples(x)
    Y = load_tuples(y)
    XY = [t for t in X if t[1] == y]
    return map(len,[X,Y,XY])