2014-09-04 123 views
10

我有一個問題,關於如何最好地寫入與python/h5py hdf5文件。h5py增量寫入hdf5

我有這樣的數據:

----------------------------------------- 
| timepoint | voltage1 | voltage2 | ... 
----------------------------------------- 
| 178  | 10  | 12  | ... 
----------------------------------------- 
| 179  | 12  | 11  | ... 
----------------------------------------- 
| 185  | 9  | 12  | ... 
----------------------------------------- 
| 187  | 15  | 12  | ... 
        ... 

用約10^4列,和大約10^7行。 (即大約10^11(1000億)元素,或者〜1GB的單位整數)。使用這些數據,典型的用法是多寫一次,多讀一次,典型的讀取例子是抓取第一列和第二列(比如254),將兩列加載到內存中,然後做一些奇妙的統計。

我認爲一個好的hdf5結構可以讓上表中的每一列成爲一個hdf5組,從而產生10^4個組。這樣我們就不需要把所有的數據讀入內存,是的?雖然hdf5結構尚未定義,所以它可以是任何東西。

現在問題: 我一次接收〜10^4行數據(每次行數不完全相同),並且需要將它逐步寫入到hdf5文件中。我如何編寫該文件?

我在考慮python和h5py,但如果推薦的話可以使用其他工具。正在分道揚the,例如

dset = f.create_dataset("voltage284", (100000,), maxshape=(None,), dtype='i8', chunks=(10000,)) 

然後當另一個10^4行的塊到達時,替換數據集?

或者將10^4行的每個塊存儲爲單獨的數據集更好嗎?或者我真的需要知道最終的行數? (這會很棘手,但也許可以)。

如果它不是工作的正確工具,我可以在hdf5上進行保釋,儘管我認爲一旦這些尷尬的寫入完成後,它會很美妙。

回答

13

Per the FAQ,您可以使用dset.resize擴展數據集。例如,

import os 
import h5py 
import numpy as np 
path = '/tmp/out.h5' 
os.remove(path) 
with h5py.File(path, "a") as f: 
    dset = f.create_dataset('voltage284', (10**5,), maxshape=(None,), 
          dtype='i8', chunks=(10**4,)) 
    dset[:] = np.random.random(dset.shape)   
    print(dset.shape) 
    # (100000,) 

    for i in range(3): 
     dset.resize(dset.shape[0]+10**4, axis=0) 
     dset[-10**4:] = np.random.random(10**4) 
     print(dset.shape) 
     # (110000,) 
     # (120000,) 
     # (130000,) 
+0

是dtype ='i8'的東西?我認爲'int8'是8位,但i8似乎更大。 – user116293 2014-09-09 18:11:46

+1

'i8'爲8字節整數。您可以使用'np.dtype('i8')。itemsize'來檢查字節大小。如果你想要1個字節的整數,使用'np.int8'(aka''i1'')。 – unutbu 2014-09-09 18:15:37

3

正如@unutbu指出,dset.resize是一個很好的選擇。看看pandas及其支持HDF5可能會很有用,這對您的工作流程可能有用。這聽起來像HDF5是一個合理的選擇給你的需求,但它可能會更好地表達你的問題使用頂部的附加層。

要考慮的一件大事是數據的方向。如果您主要對讀取感興趣,並且您主要是按列提取數據,那麼您似乎可能需要轉置數據,以便HDF5以行優先順序存儲時可以按行讀取數據。