Đọc các tập tin .mat trong Python


383

Có thể đọc tệp nhị phân MATLAB .mat trong Python không?

Tôi đã thấy rằng SciPy đã cáo buộc hỗ trợ để đọc các tệp .mat, nhưng tôi không thành công với nó. Tôi đã cài đặt SciPy phiên bản 0.7.0 và tôi không thể tìm thấy loadmat()phương thức này.

Câu trả lời:


517

Bắt buộc phải nhập, import scipy.io...

import scipy.io
mat = scipy.io.loadmat('file.mat')


18
scipy không hỗ trợ các tập tin mat v7.3 (xem ghi chú ở đây ). Xem câu trả lời của vikrantt cho giải pháp.
texnic

tuy nhiên, bạn có thể lưu tệp mat như các phiên bản trước. xem: mathworks.com/help/matlab/import_export/mat-file-versions.html (tiêu đề: 'Lưu vào phiên bản tệp MAT-Nondefault')
watsonic

5
ví dụsave('myfile.mat','-v7')
watsonic

149

Không scipy.io.savemat, cũng không scipy.io.loadmathoạt động cho mảng MATLAB phiên bản 7.3. Nhưng phần tốt là các tệp MATLAB phiên bản 7.3 là bộ dữ liệu hdf5. Vì vậy, chúng có thể được đọc bằng một số công cụ, bao gồm NumPy .

Đối với Python, bạn sẽ cần h5pyphần mở rộng, yêu cầu HDF5 trên hệ thống của bạn.

import numpy as np
import h5py
f = h5py.File('somefile.mat','r')
data = f.get('data/variable1')
data = np.array(data) # For converting to a NumPy array

6
Điều này hoạt động tốt, nếu bạn sử dụng cờ '-v7.3' trong Matlab khi lưu dữ liệu của bạn. Sử dụng mặc định save(ít nhất là trong Matlab R2014b) dẫn đến một tệp không thể đọc được bằng cách sử dụng kỹ thuật trên. Nếu bạn sử dụng cờ '-v7.3', dữ liệu số có thể được đọc tốt.
chipaudette

3
Vâng, đó là những gì tôi nói trong bài viết của mình. Bạn cần sử dụng -v7.3 trong khi lưu trong Matlab. Bạn nên làm điều đó vì nó sử dụng định dạng chuẩn hơn / được hỗ trợ / chuẩn hơn.
vikrantt

4
Bạn có thể giải thích mối quan hệ giữa fdữ liệu trong ví dụ của bạn không? Làm thế nào tôi có thể di chuyển f đến một mảng numpy?
heracho

Lưu một biến với lệnh này từ dấu nhắc:save('filename', '-v7.3', 'var1');
Kevin Katzke

23

Đầu tiên lưu tệp .mat dưới dạng:

save('test.mat', '-v7')

Sau đó, trong Python, sử dụng loadmathàm thông thường :

import scipy.io as sio
test = sio.loadmat('test.mat')

15

Có một gói đẹp được gọi là mat4pycó thể dễ dàng cài đặt bằng cách sử dụng

pip install mat4py

Nó rất đơn giản để sử dụng (từ trang web):

Tải dữ liệu từ tệp MAT

Hàm loadmattải tất cả các biến được lưu trữ trong tệp MAT vào cấu trúc dữ liệu Python đơn giản, chỉ sử dụng các đối tượng dictvà Python list. Các mảng số và ô được chuyển đổi thành các danh sách lồng nhau theo thứ tự hàng. Mảng được ép để loại bỏ mảng chỉ với một phần tử. Cấu trúc dữ liệu kết quả bao gồm các loại đơn giản tương thích với định dạng JSON .

Ví dụ: Tải tệp MAT vào cấu trúc dữ liệu Python:

from mat4py import loadmat

data = loadmat('datafile.mat')

Biến datalà a dictvới các biến và giá trị có trong tệp MAT.

Lưu cấu trúc dữ liệu Python vào tệp MAT

Dữ liệu Python có thể được lưu vào tệp MAT, với chức năng savemat. Dữ liệu phải được cấu trúc theo cách tương tự như đối với loadmat, tức là nó phải được bao gồm các kiểu dữ liệu đơn giản, giống như dict, list, str, int, và float.

Ví dụ: Lưu cấu trúc dữ liệu Python vào tệp MAT:

from mat4py import savemat

savemat('datafile.mat', data)

Tham số datasẽ là a dictvới các biến.


Lưu ý rằng mat4py cung cấp cho bạn một cây giống như json, danh sách, danh sách các danh sách ... - không hề khó chịu. ( mat4py/cmd.py my.matviết my.json, 1 dòng dài.)
denis

1
@denis: Vâng, điều đó cũng được nêu ở trên. Nhưng một điểm tốt thực sự: Tôi thường thích cấu trúc này, ví dụ như trong các ứng dụng web vì các mảng numpy không được tuần tự hóa JSON .
Khóa

Đã gặp:mat4py.loadmat.ParseError: Can only read from Matlab level 5 MAT-files
s2t2

@ s2t2: chưa bao giờ gặp phải vấn đề này trước đây. Phiên bản MATLAB nào và phiên bản scipy nào bạn đang sử dụng?
Khóa

ParseError: Chiều dài tên trường không mong đợi: 43
Fseins của Mitchsejs

13

Có MATLAB 2014b hoặc mới hơn được cài đặt, công cụ MATLAB cho Python có thể được sử dụng:

import matlab.engine
eng = matlab.engine.start_matlab()
content = eng.load("example.mat", nargout=1)

Tôi đã gặp lỗi này: ModuleNotFoundError: Không có mô-đun nào có tên 'pylab'.
Mưa

3
Bạn đã nhận được lỗi khi thử câu trả lời này? Điều đó thật kỳ lạ, nó không sử dụng pylab.
Daniel

11

Đọc tập tin

import scipy.io
mat = scipy.io.loadmat(file_name)

Kiểm tra loại biến MAT

print(type(mat))
#OUTPUT - <class 'dict'>

Các khóa bên trong từ điển là các biến MATLAB và các giá trị là các đối tượng được gán cho các biến đó .


7

Ngoài ra còn có MATLAB Engine cho Python bởi chính MathWorks. Nếu bạn có MATLAB, điều này có thể đáng để xem xét (tôi đã không tự mình thử nhưng nó có nhiều chức năng hơn là chỉ đọc các tệp MATLAB). Tuy nhiên, tôi không biết liệu có được phép phân phối nó cho những người dùng khác không (có lẽ không có vấn đề gì nếu những người đó có MATLAB. Nếu không, có lẽ NumPy là cách phù hợp?).

Ngoài ra, nếu bạn muốn tự mình thực hiện tất cả các điều cơ bản, MathWorks cung cấp (nếu liên kết thay đổi, hãy thử google matfile_format.pdfhoặc tiêu đề của nó MAT-FILE Format) một tài liệu chi tiết về cấu trúc của định dạng tệp. Nó không phức tạp như cá nhân tôi nghĩ, nhưng rõ ràng, đây không phải là cách dễ nhất để đi. Nó cũng phụ thuộc vào số lượng tính năng của .mat-files bạn muốn hỗ trợ.

Tôi đã viết một tập lệnh Python "nhỏ" (khoảng 700 dòng) có thể đọc một số tệp cơ bản .mat. Tôi không phải là chuyên gia Python cũng không phải là người mới bắt đầu và tôi mất khoảng hai ngày để viết nó (sử dụng tài liệu MathWorks được liên kết ở trên). Tôi đã học được rất nhiều thứ mới và nó khá thú vị (hầu hết thời gian). Khi tôi viết kịch bản Python tại nơi làm việc, tôi sợ rằng tôi không thể xuất bản nó ... Nhưng tôi có thể đưa ra một số lời khuyên ở đây:

  • Đầu tiên đọc tài liệu.
  • Sử dụng trình soạn thảo hex (chẳng hạn như HxD ) và xem xét một tài liệu tham khảo - .matbạn muốn phân tích cú pháp.
  • Cố gắng tìm ra ý nghĩa của từng byte bằng cách lưu các byte vào tệp .txt và chú thích từng dòng.
  • Sử dụng các lớp học để tiết kiệm mỗi phần tử dữ liệu (chẳng hạn như miCOMPRESSED, miMATRIX, mxDOUBLE, hay miINT32)
  • Các .matcấu trúc -files' là tối ưu để tiết kiệm các yếu tố dữ liệu trong một cấu trúc dữ liệu cây; mỗi nút có một lớp và mã con

9
Đó là một tài liệu điên rồ nào đó được cung cấp bởi mathworks. 40 trang giải thích định dạng, mà không đề cập rằng nó là một tập hợp con của HDF5.
Daniel

-1
from os.path import dirname, join as pjoin
import scipy.io as sio
data_dir = pjoin(dirname(sio.__file__), 'matlab', 'tests', 'data')
mat_fname = pjoin(data_dir, 'testdouble_7.4_GLNX86.mat')
mat_contents = sio.loadmat(mat_fname)

Bạn có thể sử dụng mã ở trên để đọc tệp .mat được lưu mặc định trong Python.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.