kd tree python_在Python中保存KDTree对象?

本文介绍了如何使用Scipy的KDTree实现从大文件中读取数据并构建KDTree。在构建KDTree后,讨论了如何通过pickle模块保存和加载KDTree对象,但由于KDTree内部类定义方式导致的pickle问题,提出了一个猴子补丁的解决方法,将内部类提升到模块级别以便pickle可以正确地序列化和反序列化KDTree。
摘要由CSDN通过智能技术生成

I am using Scipy's KDTree implementation to read a large file of 300 MB. Now, is there a way I can just save the datastructure to disk and load it again or am I stuck with reading raw points from file and constructing the data structure each time I start my program? I am constructing the KDTree as follows:

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!"

Any suggestions please?

解决方案

KDtree uses nested classes to define its node types (innernode, leafnode). Pickle only works on module-level class definitions, so a nested class trips it up:

import cPickle

class Foo(object):

class Bar(object):

pass

obj = Foo.Bar()

print obj.__class__

cPickle.dumps(obj)

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

However, there is a (hacky) workaround by monkey-patching the class definitions into the scipy.spatial.kdtree at module scope so the pickler can find them. If all of your code which reads and writes pickled KDtree objects installs these patches, this hack should work fine:

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]]

Output:

"ccopy_reg\n_reconstructor\np1\n(cscipy.spatial.kdtree\nKDTree\np2\nc_

[3 4] [3 4]

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值