2011-03-20 5 views
11

मैं PyTables 2.2.1 w/पायथन 2.6 का उपयोग कर रहा हूं, और मैं एक सारणी बनाना चाहता हूं जिसमें परिवर्तनीय लंबाई के नेस्टेड सरणी शामिल हैं।PyTables में, चर लंबाई की नेस्टेड सरणी कैसे बनाएं?

मैंने पीईटीबेल दस्तावेज़ों की खोज की है, और ट्यूटोरियल उदाहरण (PyTables Tutorial 3.8) दिखाता है कि लंबाई = 1 की नेस्टेड सरणी कैसे बनाएं। लेकिन इस उदाहरण के लिए, मैं डेटा 'info2/info3 पर पंक्तियों की एक चर संख्या कैसे जोड़ूं/एक्स 'और' info2/info3/y '?

शायद एक आसान समझने के लिए तालिका संरचना के लिए, यहाँ मेरी देसी उदाहरण है:

"""Desired Pytable output: 

DIEM TEMPUS Temperature    Data 
5  0  100   Category1 <--||--> Category2 
         x <--| |--> y   z <--| 
         0   0   0 
         2   1   1 
         4   1.33  2.67 
         6   1.5   4.5 
         8   1.6   6.4 
5  1  99 
         2   2   0 
         4   2   2 
         6   2   4 
         8   2   6 
5  2  96 
         4   4   0 
         6   3   3 
         8   2.67  5.33 


Note that nested arrays have variable length. 
""" 

import tables as ts 

tableDef =  {'DIEM': ts.Int32Col(pos=0), 
       'TEMPUS': ts.Int32Col(pos=1), 
       'Temperature' : ts.Float32Col(pos=2), 
       'Data': 
        {'Category1': 
         { 
         'x': ts.Float32Col(), 
         'y': ts.Float32Col() 
         }, 
        'Category2': 
         { 
         'z': ts.Float32Col(), 
         } 
        } 
       } 

# create output file 
fpath = 'TestDb.h5' 
fh = ts.openFile(fpath, 'w') 
# define my table 
tableName = 'MyData' 
fh.createTable('/', tableName, tableDef) 
tablePath = '/'+tableName 
table = fh.getNode(tablePath) 

# get row iterator 
row = table.row 
for i in xrange(3): 
    print '\ni=', i 
    # calc some fake data 
    row['DIEM'] = 5 
    row['TEMPUS'] = i 
    row['Temperature'] = 100-i**2 

    for j in xrange(5-i): 
     # Note that nested array has variable number of rows 
     print 'j=', j, 
     # calc some fake nested data 
     val1 = 2.0*(i+j) 
     val2 = val1/(j+1.0) 
     val3 = val1 - val2 

     ''' Magic happens here... 
     How do I write 'j' rows of data to the elements of 
     Category1 and/or Category2? 

     In bastardized pseudo-code, I want to do: 

     row['Data/Category1/x'][j] = val1 
     row['Data/Category1/y'][j] = val2 
     row['Data/Category2/z'][j] = val3 
     ''' 

    row.append() 
table.flush() 

fh.close() 

मैं PyTables डॉक्स कि इस तरह की संरचना संभव नहीं है में कोई संकेत नहीं मिला है ... लेकिन इस मामले में इस तरह के एक संरचना वास्तव में संभव नहीं है, परिवर्तनीय लंबाई घोंसला वाले कॉलम के मेरे विकल्प क्या हैं?

  • ईएरे? VLArray? यदि हां, तो उपरोक्त वर्णित संरचना में इन डेटा प्रकारों को एकीकृत कैसे करें?
  • कुछ अन्य विचार?

किसी भी सहायता की बहुत सराहना की जाती है! डब्ल्यू

संपादित करें/अतिरिक्त जानकारी: ऐसा प्रतीत होता है PyTables गुरु पहले से ही संबोधित किया है कि "इस तरह की संरचना संभव है" प्रश्न:

PyTables Mail Forum - Hierachical Datasets

तो किसी को भी एक अनुरूप बनाने के लिए एक तरीका खोज निकाला गया है PyTable डेटा संरचना?

फिर से धन्यवाद!

उत्तर

4

यह एक आम बात है कि पीईटीबल्स के साथ शुरू करने वाले लोग करना चाहते हैं। निश्चित रूप से, यह पहली बात थी I करने की कोशिश की। 200 9 तक, मुझे नहीं लगता कि यह कार्यक्षमता समर्थित थी। आप यहाँ देख सकते हैं एक ही समाधान के लिए "मैं हमेशा सलाह देते हैं":

http://www.mail-archive.com/[email protected]/msg01207.html

संक्षेप में, बस एक अलग जगह में प्रत्येक VLArray डाल दिया। यदि आप ऐसा करते हैं, तो हो सकता है कि आप VLArrays की आवश्यकता समाप्त न करें। यदि आप प्रत्येक परीक्षण (या जो कुछ भी) के लिए अलग-अलग VLArrays स्टोर करते हैं, तो आप उन VLArrays पर मेटाडेटा रख सकते हैं (सरणी के साथ सरणी में सिंक में रहने की गारंटी, चाल, इत्यादि) या इसे एक टेबल (खोज में आसान) में डाल दें।

लेकिन आप अपने कॉलम परमाणु के लिए जो भी समय-बिंदु होगा, उसे चुनने के लिए भी अच्छा प्रदर्शन कर सकते हैं, फिर बस टाइम स्टैंप के लिए एक और कॉलम जोड़ें। यह एक "ragged" सरणी की अनुमति देगा जो अभी भी स्मृति में एक नियमित, दोहराया (सारणीबद्ध) संरचना है। उदाहरण के लिए:

Trial Data 
1  0.4, 0.5, 0.45 
2  0.3, 0.4, 0.45, 0.56 

हो जाता है

Trial Timepoint Data 
1  1   0.4 
1  2   0.5 
... 
2  4   0.56 

डाटा ऊपर एक संख्या है, लेकिन यह हो सकता है, उदाहरण के लिए एक 4x5x3 परमाणु।

यदि नेस्टेड VLArrays अब PyTables में समर्थित हैं, तो मुझे निश्चित रूप से जानना अच्छा लगेगा!

वैकल्पिक रूप से, मुझे लगता है कि h5py पूर्ण HDF5 सुविधा-सेट का समर्थन करता है, इसलिए यदि आप वास्तव में नेस्टेड डेटा लेआउट के लिए प्रतिबद्ध हैं, तो आपके पास और अधिक भाग्य हो सकता है। यद्यपि आप बहुत अच्छी सुविधाओं पर हार जाएंगे! और मेरे अनुभव में, निष्पक्ष न्यूरोसाइजिस्टर्स काफी खराब प्रदर्शन के साथ समाप्त होते हैं क्योंकि उन्हें डेटा लेआउट, चंकिंग इत्यादि के लिए पाइटेबल्स बुद्धिमान विकल्प नहीं मिलते हैं। अगर आप उस मार्ग पर जाते हैं तो कृपया रिपोर्ट करें!

+0

सुझाव के लिए धन्यवाद! इसके अतिरिक्त, मेल-लिस्ट लिंक में फ्रांसेस्क से ज्ञान के कई अन्य रोचक 'नगेट्स' हैं। अंत में, क्योंकि मैं गति से सादगी और सादगी बनाए रखने के लिए चिंतित था, मैंने गद्दीदार अतिरिक्त जगह के साथ निश्चित सरणी आकार का चयन किया। – plmcw

0

मैं भी इसमें भाग गया और मैंने एक निश्चित सरणी आकार का उपयोग समाप्त कर दिया। सरणियों मैं दुकान की कोशिश कर रहा था चर लेन के थे तो मैं सही तय लंबाई

मैं वह मेरे लिए चाल किया

def filled_list(src_list, targ_len): 
    """takes a varible len() list and creates a new one with a fixed len()""" 
    for i in range(targ_len): 
     try: 
      yield src_list[i] 
     except IndexError: 
      yield 0 

src_list = [1,2,3,4,5,6,7,8,9,10,11] 
new_list = [x for x in filled_list(src_list, 100)] 

की तर्ज पर कुछ किया साथ से नए लोगों को बनाया।

9

मेरे पास एक समान कार्य है: एक चर लंबाई के सरणी के साथ निश्चित आकार डेटा डंप करने के लिए।

मैंने पहली बार अपने परिवर्तनीय लंबाई डेटा को स्टोर करने के लिए निश्चित आकार स्ट्रिंगकॉल (64 * 1024) फ़ील्ड का उपयोग करने का प्रयास किया (वे हमेशा < 64K हैं)। लेकिन ब्लोस्क संपीड़न के बावजूद, यह धीमी गति से और डिस्क स्थान को बर्बाद कर दिया गया था।

(स्पॉइलर:: हम अलग EArray मामलों में सरणी क्षेत्रों, एक के बाद एक सरणी प्रति EArray क्षेत्र की दुकान)

  1. मैं तय स्टोर आकार

    जांच मैं निम्नलिखित समाधान के साथ समाप्त हो गया के दिनों के बाद एक नियमित pytables तालिका में डेटा। arrFieldName_Offset और arrFieldName_Length:

    datatype = StringAtom(1) 
    buffer = h5file.createEArray('/detector', 'arr', datatype, (0,), "") 
    
  2. तब मैं:

    class Particle(IsDescription): 
        idnumber = Int64Col() 
        ADCcount = UInt16Col() 
        TDCcount = UInt8Col() 
        grid_i = Int32Col() 
        grid_j = Int32Col() 
        pressure = Float32Col() 
        energy = FloatCol() 
        buffer_Offset = UInt32() # note this field! 
        buffer_Length = UInt32() # and this one too! 
    
  3. मैं भी प्रत्येक सरणी क्षेत्र प्रति एक EArray उदाहरण बनाने

  4. मैं इन तालिकाओं के लिए 2 अतिरिक्त फ़ील्ड जोड़ा एक निश्चित आकार डेटा से संबंधित पंक्तियां जोड़ें:

    row['idnumber'] = ... 
    ... 
    row['energy'] = ... 
    row['buffer_Offset'] = buffer.nrows 
    # my_buf is a string (I get it from a stream) 
    row['buffer_Length'] = len(my_buf) 
    table.append(row) 
    
  5. ता-दाह! सरणी में बफर जोड़ें।

    buffer.append(np.ndarray((len(my_buf),), buffer=my_buf, dtype=datatype)) 
    
  6. यह चाल है। मेरे प्रयोगों में यह दृष्टिकोण रैग किए गए निश्चित आकार के सरणी (जैसे स्ट्रिंगएटॉम (एचयूजीE_NUMBER)) की तुलना में 2-10x गुना तेज है और परिणामी डीबी कुछ गुना छोटा है (2-5x)

  7. बफर डेटा प्राप्त करना आसान है। मान लीजिए कि पंक्ति एक ही पंक्ति आप अपने डीबी से पढ़ा है:

    # Open array for reading 
    buffer = h5file.createEArray('/detector', 'Particle.buffer', datatype, (0,), "") 
    ... 
    row = ... 
    ... 
    bufferDataYouNeed = buffer[ row['buffer_Offset'] : row['buffer_Offset'] + row['buffer_Length']]