Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/304.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python:存储大数据结构_Python_Data Structures_Pickle - Fatal编程技术网

Python:存储大数据结构

Python:存储大数据结构,python,data-structures,pickle,Python,Data Structures,Pickle,我目前正在用python做一个项目,它使用相对较大的字典(大约800MB)。我试着用pickle存储其中一本字典,但遇到了一个内存错误 用python保存此类文件的正确方法是什么?我应该使用数据库吗?Python标准模块为持久对象提供了类似dict的接口。它适用于许多数据库后端,不受RAM的限制。与直接使用数据库相比,使用shelve的优势在于大部分现有代码保持原样。这是以速度为代价的(与RAM DICT相比),也是以灵活性为代价的(与直接使用数据库相比)。也许您可以使用sqlite3?除非您有

我目前正在用python做一个项目,它使用相对较大的字典(大约800MB)。我试着用pickle存储其中一本字典,但遇到了一个内存错误


用python保存此类文件的正确方法是什么?我应该使用数据库吗?

Python标准模块为持久对象提供了类似dict的接口。它适用于许多数据库后端,不受RAM的限制。与直接使用数据库相比,使用
shelve
的优势在于大部分现有代码保持原样。这是以速度为代价的(与RAM DICT相比),也是以灵活性为代价的(与直接使用数据库相比)。

也许您可以使用sqlite3?除非您有一个真正的Python旧版本,否则它应该是可用的:


我没有检查sqlite3的局限性,也不知道它在您的情况下是否有用,但它值得检查。

因为它是一个字典,您可以将它转换为键值对列表(
[(k,v)]
)。然后,您可以使用任何技术(如pickle)将每个元组序列化为字符串,并将它们逐行存储到文件中。这样,并行处理、检查文件内容等也更容易


有些库允许您使用单个对象进行流式处理,但在我看来,这只会使它变得更复杂。只需逐行存储就可以消除如此多的麻烦。

当您对整个数据结构进行pickle处理时,您会受到系统RAM的限制。然而,你可以分块做

streaming pickle
看起来像是一个解决方案,用于酸洗比板上内存大的类似文件的对象


shelf
相反,
klepot
不需要将整个dict存储在单个文件中(当您只需要一个条目时,使用单个文件读写速度非常慢)。另外,与
shelf
相反,
klepot
可以存储几乎任何类型的python对象,您可以将其放入字典中(您可以存储函数、lambda、类实例、套接字、多处理队列等等)

klepot
为写入数据库提供字典抽象,包括将文件系统视为数据库(即,将整个字典写入单个文件,或将每个条目写入其自己的文件)。对于大数据,我经常选择将字典表示为文件系统上的一个目录,并将每个条目都表示为一个文件
klepot
还提供了多种缓存算法(如
mru
lru
lfu
等)来帮助您管理内存缓存,并将使用该算法为您转储和加载到存档后端

>>> from klepto.archives import dir_archive
>>> d = {'a':1, 'b':2, 'c':map, 'd':None}
>>> # map a dict to a filesystem directory
>>> demo = dir_archive('demo', d, serialized=True) 
>>> demo['a']
1
>>> demo['c']
<built-in function map>
>>> demo          
dir_archive('demo', {'a': 1, 'c': <built-in function map>, 'b': 2, 'd': None}, cached=True)
>>> # is set to cache to memory, so use 'dump' to dump to the filesystem 
>>> demo.dump()
>>> del demo
>>> 
>>> demo = dir_archive('demo', {}, serialized=True)
>>> demo
dir_archive('demo', {}, cached=True)
>>> # demo is empty, load from disk
>>> demo.load()
>>> demo
dir_archive('demo', {'a': 1, 'c': <built-in function map>, 'b': 2, 'd': None}, cached=True)
>>> demo['c']
<built-in function map>
>>> 

获取
klepot
此处:

这取决于您在这些词典中存储的内容。也许您可以很容易地尝试另一种方法(
import json;json.dumps(mydict)
,看看是否会出现相同的错误)。我已经成功地做到了这一点,对于3GB大小的文件,你是说你的字典值字段是800-MB,还是所有值的总和是800-MB?user590028-我的意思是整个结构,所有值的总和是800 MB。Tim Pietzcker-我喜欢这个想法,但是我认为它不起作用,因为这些值包含一个冻结集列表。我认为当shelve已经这样做时,这太复杂了。在我看来,一行一行地存储东西并没有那么复杂。。若你们使用架子,你们就和架子绑在一起。例如,如果逐行存储JSON,几乎任何技术都可以读取它,如Pig、Hive。此外,当数据变得非常大且不需要随机访问时,DBM文件也不是最好的。使用诸如
head
之类的工具可以很容易地检查逐行文件,这样可以更节省空间并且更难损坏。我使用shelve,因为它只需要很少的代码修改。谢谢。我考虑过了,但是需要修改代码很多。谢谢你的建议。
>>> from klepto.archives import dir_archive
>>> # does not hold entries in memory, each entry will be stored on disk
>>> demo = dir_archive('demo', {}, serialized=True, cached=False)
>>> demo['a'] = 10
>>> demo['b'] = 20
>>> demo['c'] = min
>>> demo['d'] = [1,2,3]