基本上,在 python 中存储和使用密集矩阵的最佳方法是什么?
我有一个项目,可以生成数组中每个项目之间的相似性度量。
每个项目都是一个自定义类,并存储一个指向另一个类的指针和一个表示它与该类的“接近度”的数字。
目前,它在处理约 8000 个项目时表现出色,之后就会因内存不足错误而失败。
基本上,如果您假设每次比较使用 ~30(根据测试似乎是准确的)字节来存储相似性,则意味着所需的总内存为:
numItems^2 * itemSize = Memory
因此,内存使用量根据项目数量呈指数级增长。
就我而言,每个链接的内存大小约为 30 字节,因此:
8000 * 8000 * 30 = 1,920,000,000 bytes, or 1.9 GB
这正是单线程的内存限制。
在我看来,必须有一种更有效的方法来做到这一点。我研究过内存映射,但仅仅为了生成相似性值就已经需要大量计算,并且通过硬盘驱动器来限制它似乎有点荒谬。
Edit
我看过 numpy 和 scipy。不幸的是,它们也不支持非常大的数组。
>>> np.zeros((20000,20000), dtype=np.uint16)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
MemoryError
>>>
进一步编辑
Numpy 似乎很受欢迎。然而,numpy 不会真正做我想做的事,至少没有另一个抽象层。
I don't want为了存储数字,我想存储对类的引用。 Numpy 支持对象,但这并不能真正解决数组大小问题。我提出 numpy 只是作为一个例子isn't在职的。
有什么建议吗?
Edit好吧,我最终只是重写了所有逻辑,使其不再存储任何冗余值,从而减少了内存使用量O*n^2
to O*((n*(n-1))/2)
.
基本上,这整个事件是握手问题 http://en.wikipedia.org/wiki/Handshake_problem,因此我已从存储所有链接切换为仅存储每个链接的单个版本。
这不是一个完整的解决方案,但我通常没有足够大的数据集来溢出它,所以我认为它会解决。 PyTables 确实很有趣,但我不懂任何 SQL,而且似乎没有任何好的传统切片或基于索引的方式来访问表数据。我将来可能会重新讨论这个问题。