2011-04-24 17 views
8

मैं 300 एमबी की एक बड़ी फाइल पढ़ने के लिए सिसि के केडीटी क्रियान्वयन का उपयोग कर रहा हूं। अब, क्या कोई तरीका है कि मैं सिर्फ डेटा को संरचना में सहेज सकता हूं और इसे फिर से लोड कर सकता हूं या क्या मैं फ़ाइल से कच्चे अंक पढ़ने और हर बार जब मैं अपना प्रोग्राम शुरू करता हूं तो डेटा संरचना का निर्माण कर रहा हूं? मैं केडीटी का निर्माण निम्नानुसार कर रहा हूं:पाइथन में KDTree ऑब्जेक्ट सहेज रहा है?

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

कोई सुझाव कृपया?

+1

आप अचार बनाने की कोशिश की है? – helloworld922

+0

जब मैंने KDTree ऑब्जेक्ट पर cPickle का उपयोग करने का प्रयास किया, तो मुझे अपनी मशीन – JoshAdel

उत्तर

10

केडीटी अपने घोंसले प्रकार (innernode, leafnode) को परिभाषित करने के लिए नेस्टेड कक्षाओं का उपयोग करता है। अचार केवल मॉड्यूल स्तर के वर्ग परिभाषा पर काम करता है, इसलिए एक नेस्टेड वर्ग यह यात्राएं अप:

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 

हालांकि, वहाँ एक (hacky) वैकल्पिक हल तो पिकलर मॉड्यूल गुंजाइश पर scipy.spatial.kdtree में वर्ग परिभाषाओं बंदर-पैच के द्वारा होता है उन्हें पा सकते हैं। अपने कोड जो रीड और राईट अचार KDtree वस्तुओं के सभी इन पैच को स्थापित करता है, तो यह हैक ठीक से काम करना चाहिए:

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

आउटपुट:

<class 'scipy.spatial.kdtree.innernode'> 
"ccopy_reg\n_reconstructor\np1\n(cscipy.spatial.kdtree\nKDTree\np2\nc_ 
[3 4] [3 4] 
+0

पर एक त्रुटि मिली, क्या आपके पास साइथन सीकेडीटी के लिए पैच भी होगा? – denis

+0

@ डेनिस दुर्भाग्य से मेरे पास सीकेडीटी के लिए पैच नहीं है। बचत/लोड विधि का कुछ रूप संभव होना चाहिए, लेकिन [सीकेडीटी] के बाद से अधिक कस्टम होगा (http://svn.scipy.org/svn/scipy/trunk/scipy/spatial/ckdtree.pyx) नोड्स malloc'd हैं structs, वर्ग नहीं। – samplebias

+0

दुर्भाग्यवश मुझे त्रुटि मिलती है: "पाइथन ऑब्जेक्ट को कॉल करते समय अधिकतम रिकर्सन गहराई पार हो गई" निष्पक्षता में मेरे पेड़ की गणना 5 डी समन्वय की 1,000,000 लंबी सूची पर की जाती है, क्योंकि उस सरणी से गणना करने में केवल कुछ मिनट लगते हैं (सरणी स्वयं ही मैं बचा सकता हूं और numpy के माध्यम से लोड) मुझे लगता है कि मुझे इसके साथ रहना होगा। – CastleH

संबंधित मुद्दे