内存占用高效的元组列表的简易实现结构

5

我需要创建以下类型的列表

[(latitude, longitude, date), ...]

其中纬度和经度是浮点数,日期是整数。我在本地机器上的内存不足,因为我需要存储大约6000万个这些元组。在Python中,最节省内存(同时简单实现)的表示这些元组的方法是什么?

纬度和经度的精度不需要太高(只需要足以表示像-65.100234这样的值),整数需要足够大以处理UNIX时间戳。

我以前使用过swig来定义“C结构体”,它们通常比Python更节省内存,但这很复杂...也许有一些scipy或numpy方法可以声明这样的元组,从而使用更少的内存...有什么想法吗?


2
为什么你需要将所有这些信息存储在内存中?将其存储在磁盘上不是一个选项吗? - Exelian
我确实可以将它存储到磁盘中。事实上,我是从sqlite数据库中加载它的。如果所有数据都在内存中,那么我以后想要执行的操作会更快,因为我不必执行太多的DB事务。而且,eumiro,是的,你说得对,我需要32位整数来表示Unix时间戳,我已经更新了帖子以反映这一点。 - conradlee
"sqlite" 是一种较慢的数据库,仅适用于小型数据库。而你的数据库非常庞大,因此应该使用 "mysql"。当数据库大小非常庞大时,"sqlite" 存在性能问题,但无论数据库有多大,"mysql" 都不会受到影响。所以,在我看来,应该切换到 "mysql"。无论如何,如果你正在进行一些真正的编程,迟早都要切换到 "mysql"。 - Pushpak Dagade
你可以使用诸如协议缓冲(protocol buffers)甚至标准的“struct”模块将它们编码为字节,但是每次想要使用时都需要解码,这样会有性能损失。也许你可以使用Cython,并将处理数据的函数直接翻译成C语言,以便可以将数据存储为C数组。 - Thomas K
2
Guanidene:这是一个常见的误解。特别是对于只读操作,SQLite比mysql更快。请查看此链接:http://www.sqlite.org/speed.html...但他们提到他们的比较是在一个小的数据库上进行的。 - conradlee
1个回答

3
如果您愿意使用NumPy,您可以使用numpy.recarray。如果您希望坐标保留8位有效数字,则单精度浮点数可能不够用,因此您的记录将有两个双精度浮点数和一个32位整数,总共为20个字节,因此6000万个记录需要1.2 GB内存。请注意,NumPy数组具有固定大小,如果大小更改,则需要重新分配。

代码示例:

# Create an uninitialised array with 100 records
a = numpy.recarray(100,
                   formats=["f8", "f8", "i4"],
                   names=["latitude", "longitude", "date"])
# initialise to 0
a[:] = (0.0, 0.0, 0)
# assign a single record
a[0] = (-65.100234, -38.32432, 1309351408)
# access the date of the first record
a[0].date
# access the whole date column
a.date

如果您想避免对NumPy的依赖,您也可以使用ctypes结构的ctypes数组,它们比NumPy数组不太方便,但比使用SWIG更方便。

谢谢,这就是我想要的答案。你能否补充一小段代码来展示如何使用numpy.recarray创建我想要的列表?然后我会接受你的答案。 - conradlee

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接