อ่านไฟล์. mat ใน Python


383

เป็นไปได้หรือไม่ที่จะอ่านไฟล์ไบนารี MATLAB .mat ใน Python

ฉันเคยเห็นว่า SciPy กล่าวหาว่าสนับสนุนการอ่านไฟล์. mat แต่ฉันไม่ประสบความสำเร็จ ฉันติดตั้ง SciPy เวอร์ชั่น 0.7.0 แล้วและฉันหาloadmat()วิธีไม่พบ

คำตอบ:


517

จำเป็นต้องนำเข้าimport scipy.io...

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

6
การสอน SciPy.io อย่างเป็นทางการ: docs.scipy.org/doc/scipy/reference/tutorial/io.html
Franck Dernoncourt

18
scipy ไม่รองรับไฟล์ mat v7.3 (ดูหมายเหตุที่นี่ ) ดูคำตอบโดย vikranttสำหรับการแก้ปัญหา
texnic

อย่างไรก็ตามคุณสามารถบันทึกไฟล์ mat เป็นเวอร์ชันก่อนหน้า ดูที่: mathworks.com/help/matlab/import_export/mat-file-versions.html (ส่วนหัว: 'บันทึกไปยังรุ่นเริ่มต้นไฟล์ MAT-Nondefault MAT')
watsonic

5
เช่นsave('myfile.mat','-v7')
watsonic

149

ค่าscipy.io.savematหรือscipy.io.loadmatทำงาน MATLAB เวอร์ชัน 7.3 อาร์เรย์ แต่ส่วนที่ดีคือไฟล์ MATLAB เวอร์ชั่น 7.3 เป็นชุดข้อมูล hdf5 ดังนั้นพวกเขาจึงสามารถอ่านได้โดยใช้หมายเลขของเครื่องมือรวมถึงNumPy

สำหรับ Python คุณจะต้องใช้h5pyส่วนขยายซึ่งต้องการ HDF5 ในระบบของคุณ

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
วิธีนี้ใช้งานได้ดีถ้าคุณใช้แฟล็ก '-v7.3' ใน Matlab เมื่อบันทึกข้อมูลของคุณ การใช้ค่าเริ่มต้นsave(อย่างน้อยใน Matlab R2014b) ให้ผลลัพธ์เป็นไฟล์ที่ไม่สามารถอ่านได้โดยใช้เทคนิคด้านบน หากคุณใช้แฟล็ก '-v7.3' ข้อมูลตัวเลขสามารถอ่านได้อย่างดี
chipaudette

3
ใช่นั่นคือสิ่งที่ฉันพูดในโพสต์ของฉัน คุณต้องใช้ -v7.3 ในขณะที่บันทึกใน Matlab คุณควรทำอย่างนั้นต่อไปเนื่องจากใช้รูปแบบที่ดีขึ้น / สนับสนุน / มาตรฐานมากกว่า
vikrantt

4
คุณช่วยอธิบายความสัมพันธ์ระหว่างfและข้อมูลในตัวอย่างของคุณได้อย่างไร ฉันจะย้ายfไปยังอาร์เรย์แบบ numpy ได้อย่างไร
heracho

บันทึกตัวแปรด้วยคำสั่งนี้จากพรอมต์:save('filename', '-v7.3', 'var1');
Kevin Katzke

23

ก่อนอื่นให้บันทึกไฟล์. mat เป็น:

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

หลังจากนั้นใน Python ให้ใช้loadmatฟังก์ชันปกติ:

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

15

มีแพ็คเกจที่เรียกว่าmat4pyติดตั้งได้ง่าย

pip install mat4py

มันใช้ง่าย (จากเว็บไซต์):

โหลดข้อมูลจากไฟล์ MAT

ฟังก์ชันloadmatโหลดตัวแปรทั้งหมดที่เก็บไว้ในไฟล์ MAT ลงในโครงสร้างข้อมูล Python อย่างง่ายโดยใช้เพียง Python dictและlistวัตถุ อาร์เรย์ตัวเลขและเซลล์จะถูกแปลงเป็นรายการซ้อนแบบเรียงลำดับแถว อาร์เรย์ถูกบีบเพื่อกำจัดอาร์เรย์ที่มีองค์ประกอบเดียวเท่านั้น โครงสร้างข้อมูลผลลัพธ์ประกอบด้วยชนิดง่าย ๆ ที่เข้ากันได้กับรูปแบบJSON

ตัวอย่าง: โหลดไฟล์ MAT ลงในโครงสร้างข้อมูล Python:

from mat4py import loadmat

data = loadmat('datafile.mat')

ตัวแปรdataคือdictตัวแปรและค่าที่มีอยู่ในไฟล์ MAT

บันทึกโครงสร้างข้อมูล Python ลงในไฟล์ MAT

savematข้อมูลหลามจะสามารถบันทึกเป็นเสื่อไฟล์ที่มีฟังก์ชั่น ข้อมูลจะต้องมีโครงสร้างในลักษณะเช่นเดียวกับloadmatคือมันควรจะประกอบด้วยชนิดข้อมูลง่ายเช่นdict, list, str, และintfloat

ตัวอย่าง: บันทึกโครงสร้างข้อมูล Python ไปยังไฟล์ MAT:

from mat4py import savemat

savemat('datafile.mat', data)

พารามิเตอร์dataจะต้องเป็นdictกับตัวแปร


โปรดทราบว่า mat4py ให้ต้นไม้ที่มีคำว่า dicts, list, list ของ list ... - ไม่ยุ่งยากเลย ( mat4py/cmd.py my.matเขียนmy.jsonยาว 1 บรรทัด)
denis

1
@denis: ใช่นั่นคือที่ระบุไว้ข้างต้น แต่ข้อดีอยู่ที่: ฉันมักจะชอบโครงสร้างนี้เช่นในเว็บแอปพลิเคชันเนื่องจากอาร์เรย์ที่มีจำนวนมากไม่ใช่ JSON ต่อเนื่องกันได้
Cleb

พบ:mat4py.loadmat.ParseError: Can only read from Matlab level 5 MAT-files
s2t2

@ s2t2: ไม่เคยพบปัญหานี้มาก่อน คุณใช้เวอร์ชัน matlab รุ่นใดและรุ่นใด
Cleb

ParseError: ความยาวชื่อฟิลด์ที่ไม่คาดคิด: 43
Aleksejs Fomins

13

หากมีการติดตั้ง MATLAB 2014b หรือใหม่กว่าจะสามารถใช้โปรแกรม MATLAB สำหรับ Pythonได้:

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

ฉันได้รับข้อผิดพลาดนี้: ModuleNotFoundError: ไม่มีโมดูลชื่อ 'pylab'
ฝนตก

3
คุณได้รับข้อผิดพลาดเมื่อลองคำตอบนี้? นั่นเป็นคี่มันไม่ได้ใช้ pylab
Daniel

11

กำลังอ่านไฟล์

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

การตรวจสอบชนิดของตัวแปร MAT

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

คีย์ภายในพจนานุกรมเป็นตัวแปร MATLABและค่าเป็นวัตถุที่ได้รับมอบหมายให้ตัวแปรเหล่านั้น


7

นอกจากนี้ยังมีโปรแกรมMATLAB สำหรับ Pythonโดย MathWorks เอง หากคุณมี MATLAB นี่อาจเป็นสิ่งที่ควรพิจารณา (ฉันไม่ได้ลองด้วยตัวเอง แต่มันมีฟังก์ชันการทำงานมากกว่าการอ่านไฟล์ MATLAB) อย่างไรก็ตามฉันไม่ทราบว่าได้รับอนุญาตให้แจกจ่ายให้กับผู้ใช้รายอื่นหรือไม่ (อาจไม่ใช่ปัญหาหากบุคคลเหล่านั้นมี MATLAB มิฉะนั้น NumPy อาจเป็นวิธีที่ถูกต้องหรือไม่)

นอกจากนี้หากคุณต้องการทำพื้นฐานทั้งหมดด้วยตัวเองMathWorks ก็มีให้ (หากลิงก์เปลี่ยนไปให้ลอง googlematfile_format.pdfหรือหรือชื่อMAT-FILE Format) เอกสารรายละเอียดเกี่ยวกับโครงสร้างของรูปแบบไฟล์ มันไม่ซับซ้อนอย่างที่ฉันคิดเอง แต่เห็นได้ชัดว่านี่ไม่ใช่วิธีที่ง่ายที่สุดที่จะไป นอกจากนี้ยังขึ้นอยู่กับจำนวนฟีเจอร์ของ.matไฟล์ที่คุณต้องการให้การสนับสนุน

ฉันได้เขียนสคริปต์ Python "ขนาดเล็ก" (ประมาณ 700 บรรทัด) ซึ่งสามารถอ่านพื้นฐานได้ .matได้ ฉันไม่ใช่ผู้เชี่ยวชาญของ Python และมือใหม่และใช้เวลาประมาณสองวันในการเขียน (ใช้เอกสาร MathWorks ที่ลิงก์ด้านบน) ฉันได้เรียนรู้สิ่งใหม่ ๆ มากมายและสนุกมาก (เกือบตลอดเวลา) ขณะที่ฉันเขียนสคริปต์ Python ในที่ทำงานฉันกลัวว่าฉันจะไม่เผยแพร่ ... แต่ฉันสามารถให้คำแนะนำได้ที่นี่:

  • ก่อนอ่านเอกสาร
  • ใช้ตัวแก้ไขฐานสิบหก (เช่นHxD ) และค้นหาการอ้างอิง.matคุณต้องการแยกวิเคราะห์
  • ลองค้นหาความหมายของแต่ละไบต์ด้วยการบันทึกไบต์เป็นไฟล์. txt และใส่คำอธิบายประกอบแต่ละบรรทัด
  • ใช้การเรียนการบันทึกในแต่ละองค์ประกอบของข้อมูล (เช่นmiCOMPRESSED, miMATRIX, mxDOUBLEหรือmiINT32 )
  • .matโครงสร้าง -Files' เป็นที่เหมาะสมสำหรับการประหยัดองค์ประกอบข้อมูลในโครงสร้างข้อมูลต้นไม้ แต่ละโหนดมีหนึ่งคลาสและโหนดย่อย

9
นั่นเป็นเอกสารที่บ้าคลั่งที่จัดทำโดย mathworks 40 หน้าอธิบายรูปแบบโดยไม่พูดถึงว่าเป็นชุดย่อยของ HDF5
แดเนียล

-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)

คุณสามารถใช้โค้ดด้านบนเพื่ออ่านไฟล์. mat ที่บันทึกเป็นค่าเริ่มต้นใน Python

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.