用于大型数据集的Python defaultdict

时间:2014-08-03 18:57:10

标签: python numpy defaultdict large-data

我使用defaultdict来存储数百万个短语,因此我的数据结构看起来像mydict['string'] = set(['other', 'strings'])。它似乎适用于较小的套装但是当我击中任何超过1000万个按键时,我的程序只会崩溃Process killed的有用信息。我知道defaultdict内存很重,但有一个使用defaultdict存储的优化方法,还是我必须查看其他数据结构如numpy数组?

谢谢

2 个答案:

答案 0 :(得分:4)

如果您已经开始使用单个Python进程保留在内存中,那么您将不得不放弃dict数据类型 - 如您所述,它具有出色的运行时性能特征,但它使用一堆记忆让你到那儿。

真的,我认为@ msw的评论和@ Udi的回答是现实的 - 为了扩展你应该看看磁盘或至少是某种类型的进程外存储,可能RDBMS是最容易的快点。

但是,如果您确定需要保留在内存和进程中,我建议使用排序列表来存储数据集。您可以在O(log n)时间内进行查找,并在恒定时间内进行插入和删除,并且您可以自己包装代码,以便使用看起来非常像defaultdict。这样的事情可能会有所帮助(不会在底部的测试之外进行调试):

import bisect

class mystore:
    def __init__(self, constructor):
        self.store = []
        self.constructor = constructor
        self.empty = constructor()

    def __getitem__(self, key):
        i, k = self.lookup(key)
        if k == key:
            return v
        # key not present, create a new item for this key.
        value = self.constructor()
        self.store.insert(i, (key, value))
        return value

    def __setitem__(self, key, value):
        i, k = self.lookup(key)
        if k == key:
            self.store[i] = (key, value)
        else:
            self.store.insert(i, (key, value))

    def lookup(self, key):
        i = bisect.bisect(self.store, (key, self.empty))
        if 0 <= i < len(self.store):
            return i, self.store[i][0]
        return i, None

if __name__ == '__main__':
    s = mystore(set)
    s['a'] = set(['1'])
    print(s.store)
    s['b']
    print(s.store)
    s['a'] = set(['2'])
    print(s.store)

答案 1 :(得分:2)

也许尝试redis&#39;设置数据类型:

  

Redis集是字符串的无序集合。 SADD命令添加   一组新元素。它也可以做其他一些事情   对集合的操作,如测试已经给定的元素   存在...

从这里开始:http://redis.io/topics/data-types-intro

redis-py支持这些命令。