2013-08-28 20 views
19

Her biri tek bir veri kümesi olan bir dizi hdf5 dosyam var. Veri setleri RAM'de tutmak için çok büyük. Bu dosyaları, tüm veri kümelerini ayrı olarak içeren tek bir dosyada birleştirmek istiyorum (veri kümelerini tek bir veri kümesinde birleştirmek için değil).hdf5 dosyalarını birleştirme

Bunu yapmanın bir yolu, bir hdf5 dosyası oluşturmak ve ardından veri kümelerini tek tek kopyalamaktır. Bu, arabellek kopyasının olması gerekeceği için yavaş ve karmaşık olacaktır.

Bunu yapmanın daha basit bir yolu var mı? Olması gerektiği gibi görünüyor, çünkü aslında bir kap dosyası oluşturuyor.

Python/h5py kullanıyorum.

+1

Bu sorunun yanıtlandığı anlaşılıyor: http://stackoverflow.com/questions/5346589/concatenate-a-large-number-of-hdf5-files –

+2

@MattPavelle anladığım kadarıyla bu istediğimden farklı . Veri kümelerini tek bir veri kümesinde birleştirmek istemiyorum, ancak bunları bir dosya içinde ayrı veri kümeleri olarak tutmak istiyorum. – Bitwise

+1

Anladım, açıklama ve düzenleme için teşekkürler. Ve izlemeyi affet - HDF5 ile oynadığımdan beri birkaç yıl geçti - ama h5merge'nin hile yapmadığını mı sanıyorum? –

cevap

9

Bir çözüm, düşük seviyeli HDF5 API H5Ocopyfunction için h5py arayüzü kullanmak için özellikle h5py.h5o.copyfunction: Yukarıdaki h5py sürüm 2.0.1-2+b1 ve ipython sürüm 0.13.1-2+deb7u1 oluşturulacak olan

In [1]: import h5py as h5 

In [2]: hf1 = h5.File("f1.h5") 

In [3]: hf2 = h5.File("f2.h5") 

In [4]: hf1.create_dataset("val", data=35) 
Out[4]: <HDF5 dataset "val": shape(), type "<i8"> 

In [5]: hf1.create_group("g1") 
Out[5]: <HDF5 group "/g1" (0 members)> 

In [6]: hf1.get("g1").create_dataset("val2", data="Thing") 
Out[6]: <HDF5 dataset "val2": shape(), type "|O8"> 

In [7]: hf1.flush() 

In [8]: h5.h5o.copy(hf1.id, "g1", hf2.id, "newg1") 

In [9]: h5.h5o.copy(hf1.id, "val", hf2.id, "newval") 

In [10]: hf2.values() 
Out[10]: [<HDF5 group "/newg1" (1 members)>, <HDF5 dataset "newval": shape(), type "<i8">] 

In [11]: hf2.get("newval").value 
Out[11]: 35 

In [12]: hf2.get("newg1").values() 
Out[12]: [<HDF5 dataset "val2": shape(), type "|O8">] 

In [13]: hf2.get("newg1").get("val2").value 
Out[13]: 'Thing' 

Debian Wheezy'nin bir veya daha az vanilya yüklemesinden Python versiyon 2.7.3-4+deb7u1'un üstüne. Yukarıdakileri uygulamadan önce f1.h5 ve f2.h5 dosyaları mevcut değildi. düşük seviyeli arayüz görünüşte hep diskte saklanan .h5 dosyada, bellekte önbelleğe bunun sürümünden çekecek şekilde

komuta [7] yılında hf1.flush(), çok önemlidir. Veri kümelerinin, File'un kökünde olmayan gruplara/gruplara kopyalanması, örneğin hf1.get("g1").id kullanılarak o grubun kimliğinin sağlanmasıyla sağlanabilir.belirtilen ada sahip bir nesne zaten hedef konumda olup olmadığını h5py.h5o.copy istisna (hiçbir clobber) ile başarısız olacağını

Not.

+1

Bu, potansiyel olarak birkaç yıl geç kalmış gibi görünüyor, ama ... Kesinlikle kullanacağım ve umarım başka bir şey olmasa da başkalarına da yardım eder. – hBy2Py

+1

Teşekkürler! Aslında bu soru her şimdi ve sonra oy alır, bu yüzden hala birçok insan için yararlı olduğunu tahmin ediyorum. – Bitwise

+0

Serin. HDF5 gerçekten çok güzel bir veri formatıdır, ancak yüksek seviyeli API'sı, oldukça kapsamlıdır. – hBy2Py

9

Resmi hdf5 araçlarından h5copy kullanarak python olmayan bir çözüm buldum. h5copy, bir bireysel belirtilen veri kümelerini bir hdf5 dosyasından başka bir mevcut hdf5 dosyasına kopyalayabilir.

Birisi python/h5py tabanlı bir çözüm bulursa, bunu duyduğuma sevinirim.

26

Bu aslında HDF5 kullanım durumlarından biridir. Sadece tüm veri kümelerine tek bir dosyadan erişmek ve diskte gerçekte nasıl saklandığına bakmak istemiyorsanız, external links'u kullanabilirsiniz. HDF5 website Gönderen:

Dış bağlantılar Bir grup, başka HDF5 dosyasındaki nesneleri içerir ve bunlar geçerli dosyada olduğu gibi bu nesnelere erişmek için kütüphane etkinleştirmek için izin verir. Bu şekilde, bir grup doğrudan veri kümeleri, veri kümeleri ve hatta aslında farklı bir dosyada bulunan grupları da içerebilir.

Here's how to do it in h5py: Bu özellik oluşturmak ve bağlantı adlarını tanımlamak ve dış nesnelere yollarını almak ve yorumlamak, bağlantıları yönetmek fonksiyonları bir paketi üzerinden uygulanmaktadır

myfile = h5py.File('foo.hdf5','w') 
myfile['ext link'] = h5py.ExternalLink("otherfile.hdf5", "/path/to/resource") 

Bu çok daha hızlı olacak tüm veri kümelerini yeni bir dosyaya kopyalamaktan daha fazlası. otherfile.hdf5'a ne kadar hızlı erişileceğini bilmiyorum, ancak tüm veri kümelerinde işlem şeffaf olacaktı - yani, h5py, foo.hdf5'da bulunan tüm veri kümelerini görebilecekti.

+0

Teşekkürler, bu iyi bir numara. Benim durumumda olsa, onları tek bir dosyada bulundurmayı tercih ederim. Ancak kopyalama işlemini çok yavaş olduğu kanıtlanırsa bu yöntemi kullanabilirim. – Bitwise

+2

bu sorunun cevabı olarak seçilmelidir. – ivotron

+0

Bunu yapacaksanız ve çok fazla bağlantınız varsa, H5Pset_libver_bounds() öğesini C veya libre = 'latest' ile h5py'de yeni dosyalar oluştururken/açarken kullanın. Bu, çok sayıda bağlantıyı saklamak için çok daha verimli olan en son dosya formatını kullanacaktır. –

1

Genellikle ipython ve h5copy alet togheter aletini kullanıyorum, bu saf python çözümüyle karşılaştırıldığında çok daha hızlıdır. Bir kez h5copy kurdu.

Konsol çözümü M.W.E.
#PLESE NOTE THIS IS IPYTHON CONSOLE CODE NOT PURE PYTHON 

import h5py 
#for every dataset Dn.h5 you want to merge to Output.h5 
f = h5py.File('D1.h5','r+') #file to be merged 
h5_keys = f.keys() #get the keys (You can remove the keys you don't use) 
f.close() #close the file 
for i in h5_keys: 
     !h5copy -i 'D1.h5' -o 'Output.h5' -s {i} -d {i} 

Otomatik konsol çözümü

tamamen saklanır birleştirilecek klasördeki çalışıyoruz dosyaları edildi varsayarak işlemini otomatik hale için:

import os 
d_names = os.listdir(os.getcwd()) 
d_struct = {} #Here we will store the database structure 
for i in d_names: 
    f = h5py.File(i,'r+') 
    d_struct[i] = f.keys() 
    f.close() 

# A) empty all the groups in the new .h5 file 
for i in d_names: 
    for j in d_struct[i]: 
     !h5copy -i '{i}' -o 'output.h5' -s {j} -d {j} 

her .h5 için yeni bir grup oluşturun dosya

önceki veri kümesi output.h5 içine ayrı tutmak istiyorsanız

eklendi, bayrağakullanarak ilk grubu oluşturmak zorunda:

# B) Create a new group in the output.h5 file for every input.h5 file 
for i in d_names: 
     dataset = d_struct[i][0] 
     newgroup = '%s/%s' %(i[:-3],dataset) 
     !h5copy -i '{i}' -o 'output.h5' -s {dataset} -d {newgroup} -p 
     for j in d_struct[i][1:]: 
      newgroup = '%s/%s' %(i[:-3],j) 
      !h5copy -i '{i}' -o 'output.h5' -s {j} -d {newgroup} 
1

HDF5 sürümü 1.10 ile, bu konuda güncellemek için "Sanal Veri kümeleri" olarak adlandırılan bu bağlamda yararlı olabilecek yeni bir özellik geliyor.
Burada kısa bir eğitim ve bazı açıklamalar bulabilirsiniz: Virtual Datasets. özellik için
Burada daha tam ve ayrıntılı açıklamalar ve belgeler:
Virtual Datasets extra doc.
Ve burada sanal datatsets API'sini h5py içine eklemek için h5py'deki birleştirilmiş istek isteği:
h5py Virtual Datasets PR, ancak mevcut h5py sürümünde zaten mevcut olup olmadığını veya daha sonra gelip gelmeyeceğini bilmiyorum.

+0

Bir sanal veri kümesi oluşturmak, orijinal posterin yapmak istediği şey değil, veri kümelerini (neredeyse) birleştirirdi. –

İlgili konular