gpt4 book ai didi

python - 修改 ZODB 中的数据

转载 作者:行者123 更新时间:2023-11-28 18:52:01 26 4
gpt4 key购买 nike

按照给出的建议here ,我使用 ZODB 存储了我的数据,该数据由以下代码创建:

# structure of the data [around 3.5 GB on disk]
bTree_container = {key1:[ [2,.44,0], [1,.23,0], [4,.21,0] ...[10,000th element] ], key2:[ [3,.77,0], [1,.22,0], [6,.98,0] ..[10,000th element] ] ..10,000th key:[[5,.66,0], [2,.32,0], [8,.66,0] ..[10,000th element]]}

# Code used to build the above mentioned data set
for Gnodes in G.nodes(): # Gnodes iterates over 10000 values
Gvalue = someoperation(Gnodes)
for i,Hnodes in enumerate(H.nodes()): # Hnodes iterates over 10000 values
Hvalue =someoperation(Hnodes)
score = SomeOperation on (Gvalue,Hvalue)
btree_container.setdefault(Gnodes, PersistentList()).append([Hnodes, score, 0]) # build a list corresponding to every value of Gnode (key)
if i%5000 == 0 # save the data temporarily to disk.
transaction.savepoint(True)
transaction.commit() # Flush all the data to disk

现在,我想(在一个单独的模块中)(1) 修改存储的数据并 (2) 对其进行排序。以下是我使用的代码:

storage = FileStorage('Data.fs')
db = DB(storage)
connection = db.open()
root = connection.root()
sim_sorted = root[0]

# substitute the last element in every list of every key (indicated by 0 above) by 1
# This code exhausts all the memory, never get to the 2nd part i.e. the sorting
for x in sim_sorted.iterkeys():
for i,y in enumerate(sim_sorted[x]):
y[3] = 1
if i%5000 ==0
transaction.savepoint()

# Sort all the lists associated with every key in he reverse order using middle element as key
[sim_sorted[keys].sort(key = lambda x:(-x[1])) for keys in sim_sorted.iterkeys()]

但是,用于编辑值的代码正在耗尽所有内存(永远无法排序)。我不确定这是如何工作的,但感觉我的代码存在严重错误,ZODB 将所有内容都拉入内存,因此出现了问题。达到预期效果的正确方法是什么,即在 ZODB 中替换和排序存储元素而不会遇到内存问题?代码也很慢,建议加快速度?

[注意:我没有必要将这些更改写回数据库]

编辑通过在内部循环之后添加命令 connection.cacheMinimize(),内存使用情况似乎有所改善,但是一段时间后整个 RAM 再次被消耗,这让我感到困惑。

最佳答案

您确定不是排序破坏了您的内存吗?

请注意,我希望每个 PersistentList 都必须适合内存;它是一个持久记录,因此会在访问时作为一个整体加载。

我会修改你的代码,让它像这样运行,看看会发生什么:

for x in sim_sorted.iterkeys():
for y in sim_sorted[x]:
y[3] = 1
sim_sorted[x].sort(key=lambda y: -y[1])
transaction.savepoint()

现在您一次性处理整个列表并对其进行排序;毕竟,它已经加载到内存中了。处理后,您告诉 ZODB 您已完成此阶段,整个更改列表将被刷新到临时存储。只完成一半就没有必要冲洗它。

如果这仍然不适合您的内存,您将需要重新考虑您的数据结构并将大列表拆分为较小的持久记录,这样您就可以一次处理其中的 block 而无需加载整个内容在一个。

关于python - 修改 ZODB 中的数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11335554/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com