2013-10-11 22 views
12

Tôi có một cấu trúc mảng được tạo ra bởi matlab và lưu trữ trong định dạng v7.3 mat file:Cách đọc tệp mat v7.3 qua h5py?

struArray = struct('name', {'one', 'two', 'three'}, 
        'id', {1,2,3}, 
        'data', {[1:10], [3:9], [0]}) 
save('test.mat', 'struArray', '-v7.3') 

Bây giờ tôi muốn đọc tập tin này qua python sử dụng h5py:

data = h5py.File('test.mat') 
struArray = data['/struArray'] 

Tôi không có ý tưởng làm thế nào để có được một trong những dữ liệu struct bằng một từ struArray:

for index in range(<the size of struArray>): 
    elem = <the index th struct in struArray> 
    name = <the name of elem> 
    id = <the id of elem> 
    data = <the data of elem> 
+0

Bạn đã tìm thấy một giải pháp thực tế cho việc này? – Pastafarian

+0

Tôi có một câu hỏi tương tự, với một giải pháp từng phần: http://stackoverflow.com/questions/29852481/reading-all-variables-in-a-mat-file-with-python-h5py/29856030#29856030 – CodyF

Trả lời

0

Matlab định dạng tập tin 7.3 không phải là vô cùng dễ dàng để làm việc với h5py. Nó dựa trên tham khảo HDF5, cf. h5py documentation on references.

>>> import h5py 
>>> f = h5py.File('test.mat') 
>>> list(f.keys()) 
['#refs#', 'struArray'] 
>>> struArray = f['struArray'] 
>>> struArray['name'][0, 0] # this is the HDF5 reference 
<HDF5 object reference> 
>>> f[struArray['name'][0, 0]].value # this is the actual data 
array([[111], 
     [110], 
     [101]], dtype=uint16) 

Để đọc struArray(i).id:

>>> f[struArray['id'][0, 0]][0, 0] 
1.0 
>>> f[struArray['id'][1, 0]][0, 0] 
2.0 
>>> f[struArray['id'][2, 0]][0, 0] 
3.0 

ý rằng Matlab cửa hàng một số như một mảng có kích thước (1, 1), do đó trận chung kết [0, 0] để có được số điện thoại.

Để đọc struArray(i).data:

>>> f[struArray['data'][0, 0]].value 
array([[ 1.], 
     [ 2.], 
     [ 3.], 
     [ 4.], 
     [ 5.], 
     [ 6.], 
     [ 7.], 
     [ 8.], 
     [ 9.], 
     [ 10.]]) 

Để đọc struArray(i).name, nó là cần thiết để chuyển đổi các mảng các số nguyên để chuỗi:

>>> f[struArray['name'][0, 0]].value.tobytes()[::2].decode() 
'one' 
>>> f[struArray['name'][1, 0]].value.tobytes()[::2].decode() 
'two' 
>>> f[struArray['name'][2, 0]].value.tobytes()[::2].decode() 
'three' 
0

tôi sẽ bắt đầu bằng cách bắn lên người phiên dịch và chạy help trên struarray. Nó sẽ cung cấp cho bạn đủ thông tin để giúp bạn bắt đầu. Nếu không, bạn có thể đổ các thuộc tính của bất kỳ đối tượng Python nào bằng cách print ing thuộc tính __dict__.

0

Tôi xin lỗi nhưng tôi nghĩ sẽ rất khó khăn để lấy nội dung của các ô/cấu trúc từ bên ngoài Matlab. Nếu bạn xem các tập tin được tạo ra (ví dụ với HDFView), bạn sẽ thấy có rất nhiều tham chiếu chéo và không có cách nào rõ ràng để tiến hành.

Nếu bạn dính vào mảng số đơn giản, nó hoạt động tốt. Nếu bạn có mảng ô nhỏ chứa mảng số, bạn có thể chuyển đổi chúng thành các biến riêng biệt (ví dụ cellcontents1, cellcontents2, v.v.) thường chỉ là một vài dòng và cho phép chúng được lưu và tải trực tiếp. Vì vậy, trong ví dụ của bạn, tôi sẽ lưu một tệp có vars name1, name2, name3, id1, id2, id3 ... v.v.

EDIT: Bạn đã chỉ định h5py trong câu hỏi để trả lời những gì tôi đã trả lời, nhưng đáng lưu ý rằng với scipy.io.loadmat bạn sẽ có thể nhận các biến ban đầu được chuyển thành tương đương (ví dụ: mảng đối tượng).

+4

Thanks anyway ! Tôi đã đấu tranh với vấn đề này một vài ngày. Tôi luôn luôn có một cái gì đó giống như '' chứ không phải là giá trị thực. Tuy nhiên, 'scipy.io.loadmat' không hoạt động với định dạng v7.3 của tệp mat. – Eastsun

-1

Đó thực sự là vấn đề với Matlab 7.3 và h5py. Bí quyết của tôi là chuyển đổi loại h5py._hl.dataset.Dataset thành mảng numpy. Ví dụ:

np.array(data['data']) 

sẽ giải quyết vấn đề của bạn với trường 'data'.

+0

Không hoạt động. Chỉ cần thêm một lớp mảng trên đầu trang của một hiện có. Ví dụ. 'mảng ([<đối tượng tham chiếu HDF5>, , ]], dtype = object)' Và dữ liệu hiện có IS thuộc loại 'h5py._hl.dataset.Dataset' – Pastafarian

2

visit hoặc visititems là cách nhanh chóng để nhìn thấy cấu trúc tổng thể của một tập tin h5py:

fs['struArray'].visititems(lambda n,o:print(n, o)) 

Khi tôi chạy trên một tập tin được tạo ra bởi Octave save -hdf5 tôi nhận được:

type <HDF5 dataset "type": shape(), type "|S7"> 
value <HDF5 group "/struArray/value" (3 members)> 
value/data <HDF5 group "/struArray/value/data" (2 members)> 
value/data/type <HDF5 dataset "type": shape(), type "|S5"> 
value/data/value <HDF5 group "/struArray/value/data/value" (4 members)> 
value/data/value/_0 <HDF5 group "/struArray/value/data/value/_0" (2 members)> 
value/data/value/_0/type <HDF5 dataset "type": shape(), type "|S7"> 
value/data/value/_0/value <HDF5 dataset "value": shape (10, 1), type "<f8"> 
value/data/value/_1 <HDF5 group "/struArray/value/data/value/_1" (2 members)> 
... 
value/data/value/dims <HDF5 dataset "dims": shape (2,), type "<i4"> 
value/id <HDF5 group "/struArray/value/id" (2 members)> 
value/id/type <HDF5 dataset "type": shape(), type "|S5"> 
value/id/value <HDF5 group "/struArray/value/id/value" (4 members)> 
value/id/value/_0 <HDF5 group "/struArray/value/id/value/_0" (2 members)> 
... 
value/id/value/_2/value <HDF5 dataset "value": shape(), type "<f8"> 
value/id/value/dims <HDF5 dataset "dims": shape (2,), type "<i4"> 
value/name <HDF5 group "/struArray/value/name" (2 members)> 
... 
value/name/value/dims <HDF5 dataset "dims": shape (2,), type "<i4"> 

này có thể không giống như những gì MATLAB 7.3 tạo ra, nhưng nó đưa ra một ý tưởng về sự phức tạp của cấu trúc.

Gọi lại tinh tế hơn có thể hiển thị giá trị và có thể là điểm bắt đầu để tạo lại đối tượng Python (từ điển, danh sách, v.v.).

def callback(name, obj): 
    if name.endswith('type'): 
     print('type:', obj.value) 
    elif name.endswith('value'): 
     if type(obj).__name__=='Dataset': 
      print(obj.value.T) # http://stackoverflow.com/questions/21624653 
    elif name.endswith('dims'): 
     print('dims:', obj.value) 
    else: 
     print('name:', name) 

fs.visititems(callback) 

sản xuất:

name: struArray 
type: b'struct' 
name: struArray/value/data 
type: b'cell' 
name: struArray/value/data/value/_0 
type: b'matrix' 
[[ 1. 2. 3. 4. 5. 6. 7. 8. 9. 10.]] 
name: struArray/value/data/value/_1 
type: b'matrix' 
[[ 3. 4. 5. 6. 7. 8. 9.]] 
name: struArray/value/data/value/_2 
type: b'scalar' 
0.0 
dims: [3 1] 
name: struArray/value/id 
type: b'cell' 
name: struArray/value/id/value/_0 
type: b'scalar' 
1.0 
... 
dims: [3 1] 
name: struArray/value/name 
type: b'cell' 
name: struArray/value/name/value/_0 
type: b'sq_string' 
[[111 110 101]] 
... 
dims: [3 1] 
Các vấn đề liên quan