2014-09-04 20 views
10

Tôi có một câu hỏi về cách tốt nhất để ghi vào tệp hdf5 bằng python/h5py.gia tăng ghi vào hdf5 với h5py

Tôi có dữ liệu như:

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

với khoảng 10^4 cột, và khoảng 10^7 hàng. (Đó là khoảng 10^11 (100 tỷ) yếu tố, hoặc ~ 100GB với 1 byte ints).

Với dữ liệu này, sử dụng điển hình là viết nhiều lần, đọc nhiều lần và trường hợp đọc điển hình là lấy cột 1 và cột khác (nói 254), tải cả hai cột vào bộ nhớ và thực hiện một số thống kê ưa thích .

Tôi nghĩ rằng cấu trúc hdf5 tốt do đó sẽ có mỗi cột trong bảng ở trên là nhóm hdf5, dẫn đến 10^4 nhóm. Bằng cách đó, chúng tôi sẽ không cần phải đọc tất cả dữ liệu vào bộ nhớ, phải không? Cấu trúc hdf5 chưa được xác định, vì vậy nó có thể là bất cứ thứ gì.

Bây giờ câu hỏi: Tôi nhận dữ liệu ~ 10^4 hàng tại một thời điểm (và không chính xác cùng số hàng mỗi lần) và cần ghi nó theo từng bước vào tệp hdf5. Làm thế nào để tôi viết tập tin đó?

Tôi đang xem xét python và h5py, nhưng có thể một công cụ khác nếu được đề xuất. Đang chunking con đường để đi, với ví dụ

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

và sau đó khi một khối khác có 10^4 hàng đến, hãy thay thế tập dữ liệu?

Hoặc tốt hơn là chỉ lưu trữ mỗi khối 10^4 hàng dưới dạng tập dữ liệu riêng biệt? Hay tôi thực sự cần phải biết số hàng cuối cùng? (Sẽ rất khó để có được, nhưng có thể có thể).

Tôi có thể bảo lãnh trên hdf5 nếu nó không phải là công cụ phù hợp cho công việc, mặc dù tôi nghĩ rằng một khi viết lúng túng được thực hiện, nó sẽ rất tuyệt vời.

Trả lời

13

Per the FAQ, bạn có thể mở rộng tập dữ liệu bằng cách sử dụng dset.resize. Ví dụ:

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

là dtype = 'i8' một điều? Tôi nghĩ 'int8' là 8 bit, nhưng i8 có vẻ lớn hơn. – user116293

+1

'i8' dành cho int 8 byte. Bạn có thể kiểm tra kích thước byte bằng cách sử dụng 'np.dtype ('i8'). Itemsize'. Nếu bạn muốn int 1 byte, sử dụng 'np.int8' (aka' 'i1''). – unutbu

3

Như @unutbu chỉ ra, dset.resize là một lựa chọn tuyệt vời. Nó có thể hoạt động trong khi xem xét pandas và hỗ trợ HDF5 có thể hữu ích cho quy trình làm việc của bạn. Nghe có vẻ như HDF5 là một lựa chọn hợp lý cho nhu cầu của bạn nhưng có thể vấn đề của bạn có thể được thể hiện tốt hơn bằng cách sử dụng một lớp bổ sung ở trên cùng.

Một điều quan trọng cần xem xét là định hướng của dữ liệu. Nếu bạn chủ yếu quan tâm đến lần đọc và bạn chủ yếu tìm nạp dữ liệu theo cột, thì có vẻ như bạn có thể muốn chuyển dữ liệu sao cho lần đọc có thể xảy ra theo hàng khi cửa hàng HDF5 theo thứ tự hàng lớn.

Các vấn đề liên quan