2011-03-20 22 views
11

PyTables 2.2.1 w/Python 2.6 kullanıyorum ve değişken uzunluklu iç içe geçmiş diziler içeren bir tablo oluşturmak istiyorum.PyTables'ta, değişken uzunluklu yuvalanmış dizi nasıl oluşturulur?

PyTables belgelerini aradım ve öğretici örneği (PyTables Tutorial 3.8), yuvalanmış bir uzunluk dizisi = 1'in nasıl oluşturulacağını gösterir. Ancak bu örnekte, değişkenlere ait bir satır sayısını veriye nasıl ekleyebilirim? Info2/info3/x 've' info2/info3/y '? belki daha kolay bir anlama tablo yapısı için

, burada benim homegrown örnek: Ben böyle bir yapı mümkün değildir PyTables docs herhangi bir gösterge bulamadık

"""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() 

... ama durum böyle Yapı aslında mümkün değil, değişken uzunlukta iç içe geçmiş sütunlara alternatiflerim nelerdir?

  • EArray? VLArray? Öyleyse, bu veri türlerini yukarıda açıklanan yapıya nasıl entegre edebiliriz?
  • başka bir fikir?

Her türlü yardım büyük önem taşır!

DÜZENLEME/ek bilgi w:

PyTables Mail Forum - Hierachical Datasets

Yani herkes benzer bir oluşturmak için bir yolunu bulmuş: PyTables gurular zaten "Böyle bir yapı mümkündür" sorusunu ele anlaşılıyor PyTable veri yapısı?

Tekrar teşekkürler!

cevap

4

Bu, PyTables ile başlayan kişilerin yapmak istediği ortak bir şeydir. Şüphesiz, bu ilk denemenin yapıldığı ilk şey I idi. 2009 itibariyle, bu işlevin desteklendiğini düşünmüyorum. Burada bakabilirsiniz bir çözüm için "Hep tavsiye": Kısacası

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

, sadece ayrı bir yerde her VLArray koydu. Bunu yaparsan belki de VLArrays'a ihtiyaç duymazsın. Her bir deneme için ayrı VLArrays depolarsanız (ya da her neyse), bu VLArrays'larda meta verileri saklayabilir (dizi, hareketler, vb. Boyunca diziyle uyumlu kalması garanti edilir) ya da bir tabloya koyabilirsiniz (daha kolay arama).

Ayrıca, sütun atomunuz için tek bir zaman noktası ne olursa olsun seçmek için de iyi olabilir, daha sonra bir zaman damgası için başka bir sütun ekleyin. Bu, bellekte düzenli, tekrarlanan (tablo) bir yapıya sahip olan bir "düzensiz" diziye izin verir. Örneğin: örneğin

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 

veriler üzerinde tek sayıdır olur, ama olabilir 4x5x3 atom.

İç içe geçmiş VLArrays şimdi PyTables içinde destekleniyorsa, kesinlikle bunu bilmek isterim!

Alternatif olarak, h5py'nin tam HDF5 özellik kümesini desteklediğini düşünüyorum. Bu nedenle, yuvalanmış veri düzenine gerçekten bağlıysanız, orada daha fazla şansınız olabilir. Yine de birçok güzel özelliği kaybediyor olacaksınız! Ve tecrübelerime göre, naif nörobilimciler veri düzeni, yığınlama vb. Için akıllı seçimler yapmadıkları için oldukça zayıf bir performansla sonuçlanıyorlar. Lütfen bu rotayı izlerseniz rapor verin!

+0

Teşekkür: satır Eğer DB'den okunan tek bir satır olduğunu varsayalım! Ek olarak, posta listesi bağlantısında Francesc'den başka bir ilginç 'nuggets' bilgelik var. Sonunda, hız ile ilgilendiğim ve basitliği koruduğum için, yastıklı ekstra alanla sabit dizi boyutunu seçtim. – plmcw

0

Buna da rastladım ve sabit bir dizi boyutu kullanarak sona erdim. Bana göre bir hile yaptı

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

çizgisinde bir şey yaptım doğru sabit uzunlukta

ile yenilerini yarattı yüzden mağazaya çalışıyordum diziler değişken len vardı.

9

Benzer bir görevim var: Değişken uzunluktaki dizilerle sabit boyutlu verileri atmak.

Değişken uzunluktaki verilerimi depolamak için sabit boyutlu StringCol (64 * 1024) alanlarını kullanmayı denedim (her zaman < 64K'tır). Ancak blosc sıkıştırmasına rağmen oldukça yavaş ve çok fazla disk alanı harcadı.

(rüzgarlık: Biz ayrı EArray durumlarda dizi alanları, bir EArray bir dizi başına alan saklamak)

  1. I sabit depolamak boyutu

    aşağıdaki çözelti ile sona eren soruşturma gün sonra Normal bir pateryum tablosundaki veriler.arrFieldName_Offset ve arrFieldName_Length: I

    datatype = StringAtom(1) 
    buffer = h5file.createEArray('/detector', 'arr', datatype, (0,), "") 
    
  2. Ardından:

    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. Ayrıca her bir dizi alan başına bir EArray örneği oluşturmak

  4. I bu tablolara 2 ek alan eklendi Sabit boyutlu verilere karşılık gelen satırları ekleyin:

    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. Ta-dah! Tamponu diziye ekleyin.

    buffer.append(np.ndarray((len(my_buf),), buffer=my_buf, dtype=datatype)) 
    
  6. Bu numaradır. Benim deneyimlerimde bu yaklaşım, düzensiz sabit boyutlu dizileri (StringAtom (HUGE_NUMBER) gibi) saklamaktan 2-10 kat daha hızlıdır ve sonuçta elde edilen DB, birkaç kez daha küçüktür (2-5x)

  7. Arabellek verileri almak kolaydır. Öneriler için

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