首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在Python中保存KDTree对象?

在Python中保存KDTree对象?
EN

Stack Overflow用户
提问于 2011-04-25 04:58:19
回答 1查看 3.7K关注 0票数 11

我正在使用Scipy的KDTree实现来读取300MB的大文件。现在,有没有一种方法可以将数据结构保存到磁盘并重新加载它,或者每次启动程序时,我都要从文件中读取原始点并构建数据结构?我构建KDTree的方法如下:

代码语言:javascript
复制
def buildKDTree(self):
        self.kdpoints = numpy.fromfile("All", sep=' ')
        self.kdpoints.shape = self.kdpoints.size / self.NDIM, NDIM
        self.kdtree = KDTree(self.kdpoints, leafsize = self.kdpoints.shape[0]+1)
        print "Preparing KDTree... Ready!"

有什么建议吗?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2011-04-25 08:27:06

KDtree使用嵌套类来定义其节点类型(内部节点、叶节点)。Pickle只适用于模块级的类定义,因此嵌套类会使其出错:

代码语言:javascript
复制
import cPickle

class Foo(object):
    class Bar(object):
        pass

obj = Foo.Bar()
print obj.__class__
cPickle.dumps(obj)

<class '__main__.Bar'>
cPickle.PicklingError: Can't pickle <class '__main__.Bar'>: attribute lookup __main__.Bar failed

然而,有一个(老生常谈的)解决办法,那就是在模块范围内将类定义修补到scipy.spatial.kdtree中,这样pickler就可以找到它们。如果你的所有读写KDtree对象的代码都安装了这些补丁,那么这个技巧应该可以很好地工作:

代码语言:javascript
复制
import cPickle
import numpy
from scipy.spatial import kdtree

# patch module-level attribute to enable pickle to work
kdtree.node = kdtree.KDTree.node
kdtree.leafnode = kdtree.KDTree.leafnode
kdtree.innernode = kdtree.KDTree.innernode

x, y = numpy.mgrid[0:5, 2:8]
t1 = kdtree.KDTree(zip(x.ravel(), y.ravel()))
r1 = t1.query([3.4, 4.1])
raw = cPickle.dumps(t1)

# read in the pickled tree
t2 = cPickle.loads(raw)
r2 = t2.query([3.4, 4.1])
print t1.tree.__class__
print repr(raw)[:70]
print t1.data[r1[1]], t2.data[r2[1]]

输出:

代码语言:javascript
复制
<class 'scipy.spatial.kdtree.innernode'>
"ccopy_reg\n_reconstructor\np1\n(cscipy.spatial.kdtree\nKDTree\np2\nc_
[3 4] [3 4]
票数 12
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/5773216

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档