3

我有以下字典结构( 10,000 个键,其值由列表列表形成)

my_dic ={0: [[1,.65,3, 0, 5.5], [[4, .55, 3, 0, 5.5] ...(10,000th value)[3,.15, 2, 1,   2.5]], 
1:[[1,.65,3, 0, 5.5], [[4, .55, 3, 0, 5.5] ...(10,000th value)[3,.15, 2, 1, 2.5]] .....   
10,000th key:[[1,.65,3, 0, 5.5], [[4, .55, 3, 0, 5.5] ...(10,000th value)[3,.15, 2, 1, 2.5]]}

(注意:数据是虚拟的,所以我只是在键中重复了它)

我想要在较小的基本列表中的逻辑数据类型是

inner_list = [int, float, small_int, boolean( 0 or 1), float]

A sys.getsizeof(inner_list), 显示它的大小为56字节。为 int 键添加12字节使其成为68字节。现在,由于我有10^8这样的列表(10000*10000),它在内存中的存储正成为一个大问题。我想要内存中的数据(目前没有数据库)。存储它的最优化方法应该是什么?我倾向于认为它一定与numpy但不确定什么是最好的方法以及如何实施它。有什么建议么 ?

2)另外,由于我将这些字典存储在内存中,所以我想在使用完它们后立即清除它们占用的内存。有没有办法在python中做到这一点?

4

1 回答 1

2

一种想法是将字典结构分解为更简单的结构,但这可能会影响您处理它的效率。

1为键创建单独的数组

keys = array('i', [key1, key2, ..., key10000])

根据键的可能值,您可以进一步指定数组的特定 int 类型。此外,键应该是有序的,因此您可以在键表上执行二进制搜索。这样,您还可以从 Python 字典实现中使用的哈希表中节省一些空间。缺点是密钥查找现在需要O(logn)时间而不是O(1).

2 将 inner_list 元素存储在 10000x10000 矩阵或 100000000 长度列表中

由于从 0 到 9999 的每个位置都i对应一个特定的键,可以从 keys 数组中获取,因此可以将每个列表列表放入i矩阵的第 ' 行,并将每个inner_list元素放入该行的列中。

其他选择是将它们放在一个长列表中并使用关键位置进行索引,i这样

idx = i*10000 + j

其中i是键数组中键j的索引,是特定inner_list实例的索引。

此外,对于每个inner_list元素,您总共可以拥有五个单独的数组,这在一定程度上破坏了内存中数据的局部性

int_array = array('i', [value1, ..., value100000000])
float1_array = array('f', [value1, ..., value100000000])
small_int_array = array('h', [value1, ..., value100000000])
bool_array = array('?', [value1, ..., value100000000])
float2_array = array('f', [value1, ..., value100000000])

布尔数组可以通过将它们打包成位来进一步优化。

另一种方法是使用structinner_list模块将元素打包在二进制字符串中,并将它们存储在单个列表中,而不是五个不同的列表中。

3 释放内存

一旦变量超出范围,它们就准备好被垃圾收集,因此可以收回内存。为了更快地执行此操作,例如在函数或循环中,您可能只需将列表替换为虚拟值,以将变量的引用计数降至零。

variable = None

笔记

但是,这些想法对于您的特定解决方案可能还不够好。还有其他可能性,例如仅将部分数据加载到内存中。这取决于您打算如何处理它。

通常,Python 会占用自己的内存份额来处理指针/结构的内部处理。因此,另一种选择是使用 Fortran、C 或 C++ 等语言来实现特定的数据结构及其处理,这些语言可以更容易地针对您的特定需求进行调整。

于 2012-07-19T03:15:28.357 回答