Python:在内存中有效存储数据

时间:2012-07-19 02:19:27

标签: python memory-management dictionary

我有以下字典结构(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]]}

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

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

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

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

2)另外,由于我将这些词典存储在内存中,因此我想在使用它们后立即清除它们占用的内存。有没有办法在python中这样做?

1 个答案:

答案 0 :(得分:2)

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

1为密钥

创建单独的array
keys = array('i', [key1, key2, ..., key10000])

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

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

由于0到9999之间的每个位置i对应于可以从keys数组中获取的特定键,因此每个列表列表都可以放入矩阵中的i'行,每个{行中列中的{1}}元素。

其他选项是使用关键位置inner_list将它们放入长列表和索引中,以便

i

其中idx = i*10000 + j 是keys数组中键的索引,i是特定j实例的索引。

此外,对于每个inner_list元素,您可以总共有五个单独的数组,这有点会破坏内存中数据的位置

inner_list

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

替代方法也是使用struct模块将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]) 元素打包在二进制字符串中,并将它们存储在单个列表中而不是五个不同的列表中。

3释放内存

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

inner_list

注意

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

通常,Python会将自己的内存份额用于内部处理指针/结构。因此,另一种替代方法是使用Fortran,C或C ++等语言实现特定的数据结构及其处理,可以更轻松地根据您的特定需求进行调整。