高效的大型dicts代表Python中的M:M关系

时间:2011-03-14 18:34:19

标签: python data-structures

我有一个非常大的数据集 - 数百万条记录 - 我想用Python存储。我可能在32位计算机上运行,​​因此我希望将数据集保持在数百MB的范围内,而不是比这更大的膨胀。

这些记录 - 代表M:M关系 - 两个ID(foo和bar)和一些简单的元数据,如时间戳(baz)。

有些foo几乎都在其中,而且有些酒吧几乎都是foo。但是有很多酒吧几乎没有任何元素和许多几乎没有酒吧的泡沫。

如果这是关系数据库,则M:M关系将被建模为具有复合键的表。您当然可以舒适地搜索任一组件键。

但是,如果将行存储在哈希表中,则需要维护三个哈希表,因为复合键经过哈希处理,您无法使用它搜索组件键。

如果您有某种排序索引,则可以滥用词法排序来迭代复合键中的第一个键,并且需要另一个键的第二个索引;但是对我来说不太明显的是,标准Python集合中的实际数据结构等同于什么。

我正在考虑一个foo的dict,其中每个值都会自动从元组(单行)移动到列表(行元组)到dict,具体取决于某些阈值,另一个bar的dict,其中每个都是单个foo,或者foo列表。

是否有更有效的方法 - 速度和空间 - 这样做的方法? 指数或其他任何类型的numpy?


(我想将它们存储在Python中,因为我遇到了数据库的性能问题 - 无论是SQL还是NoSQL。你最终都是IPC memcpy和序列化绑定。这是另一个故事;但关键是我想要的将数据移动到应用程序中而不是获得将其移出应用程序的建议;))

4 个答案:

答案 0 :(得分:2)

您是否考虑使用在Redis内存中运行的NoSQL数据库? Redis支持大量熟悉的数据结构。

我意识到你不想移出应用程序,但不重新发明轮子可以节省时间,坦率地说它可能更有效率。

答案 1 :(得分:2)

如果您需要以灵活的方式查询数据并维护各种关系,我建议您继续使用数据库,其中有许多选项。如何使用内存数据库,如sqlite(使用“:memory:”作为文件)?您并没有真正将数据移动到程序之外,并且您将比使用多层dicts更具灵活性。

Redis也是一个有趣的选择,因为它有其他数据结构可供使用,而不是使用SQL的关系模型。

答案 2 :(得分:2)

你描述的内容听起来像一个稀疏矩阵,其中foos沿着一个轴,而条带沿着另一个轴。每个非空单元格表示一个foo和一个条形之间的关系,并包含您描述的“简单元数据”。

你应该看一下Python(scipy.sparse,PySparse)的高效稀疏矩阵包。我只是通过谷歌搜索“python稀疏矩阵”找到了这两个。

关于使用数据库,您声称自己遇到了性能问题。我想建议您可能没有选择最佳表示,但如果没有关于访问模式的详细信息以及您使用的数据库模式的详细信息,那么任何人都很难提供有用的帮助。您可以考虑编辑帖子以提供更多信息。

答案 3 :(得分:0)

像redis这样的NoSQL系统不提供MM表。

最后,一个由持有值的对键控制的python dict,以及每个术语的一组配对的dict是我能想到的最好的。

class MM:
    def __init__(self):
        self._a = {} # Bs for each A
        self._b = {} # As for each B
        self._ab = {}