HOWTO · Python

Leggi i file Matlab mat in Python

Questo tutorial mostra come leggere e aprire i file mat Matlab in Python

In questa pagina

MATLAB salva le variabili del workspace in file .mat, e Python non offre un modo integrato per aprirli: la libreria di lettura si sceglie in base alla versione del MAT-file. Questa guida mostra come identificare il formato di un file e caricarne le variabili con scipy.io, h5py, mat4py o l’API matlab.engine, e spiega dove ciascun approccio smette di funzionare.

Scegli un lettore in base alla versione del MAT-file

MATLAB ha usato due layout di file. Le versioni di MAT-file dalla 5 alla 7.2 usano il formato binario proprietario di MATLAB e iniziano con un’intestazione testuale di 128 byte che comincia con MATLAB; i file MATLAB 4, ancora più vecchi, usano lo stesso layout classico ma non hanno un’intestazione descrittiva: iniziano direttamente con gli elementi dati. scipy.io.loadmat legge l’intera famiglia classica, con o senza intestazione. I file salvati con -v7.3 sono file HDF5: mantengono un piccolo user block MATLAB ma memorizzano i dati come dataset HDF5, ed è ciò che h5py apre. NumPy da solo non può aprire nessuno dei due layout: si limita a convertire in array un dataset già caricato.

Puoi identificare un file senza installare nulla osservandone i primi byte. Esegui questo esempio, che scrive un file di ciascun tipo comune in una cartella temporanea e li classifica in base all’intestazione:

Il codice e le etichette o gli output visibili in questa sezione restano in inglese.

import os
import tempfile

folder = tempfile.mkdtemp()
classic = os.path.join(folder, "classic.mat")
modern = os.path.join(folder, "v73.mat")

with open(classic, "wb") as f:
    f.write(b"MATLAB 5.0 MAT-file, Platform: GLNXA64, Created on: Thu Oct 29 2026".ljust(128, b" "))

with open(modern, "wb") as f:
    f.write(b"MATLAB 7.3 MAT-file, Platform: GLNXA64, HDF5 schema 1.00".ljust(512, b" "))
    f.write(b"\x89HDF\r\n\x1a\n")

def mat_kind(path):
    with open(path, "rb") as f:
        head = f.read(128)
        f.seek(512)
        signature = f.read(8)
    if b"HDF5" in head or signature.startswith(b"\x89HDF"):
        return "MATLAB 7.3 (HDF5): read with h5py"
    if head.startswith(b"MATLAB"):
        return "MAT-file 7.2 or older: read with scipy.io.loadmat"
    return "no v5+ header or HDF5 signature — possibly a MATLAB 4 file: try scipy.io.loadmat"

print(mat_kind(classic))
print(mat_kind(modern))
MAT-file 7.2 or older: read with scipy.io.loadmat
MATLAB 7.3 (HDF5): read with h5py

Un vero file 7.3 menziona HDF5 nel testo dell’intestazione e porta la firma HDF5 dopo lo user block, mentre l’intestazione di un file di versione 5–7.2 inizia semplicemente con MATLAB. Il controllo classifica solo in base a questi due marcatori: un file MATLAB 4 non ne mostra nessuno dei due, quindi finisce sul messaggio di fallback, ma scipy.io.loadmat lo apre comunque; considera quel risultato come un invito a provare direttamente loadmat, non come prova che il file sia illeggibile. Come regola generale, usa scipy.io.loadmat quando il file è di versione 7.2 o precedente, h5py per i file 7.3, mat4py quando da un file classico vuoi semplici liste Python invece di array NumPy, e matlab.engine solo quando MATLAB stesso è installato e ti serve la massima fedeltà per i tipi complessi. Una volta che le variabili sono in Python, pandas può esportarle in CSV o Excel, e scipy.io.savemat o un dataset HDF5 possono riscrivere un file .mat se in seguito ne hai bisogno.

Le sezioni seguenti usano sample.mat (un file classico) e sample_v73.mat (un file 7.3), che si presume contengano una variabile chiamata measurements. Quei frammenti sono specifici per la dipendenza: presuppongono che il pacchetto indicato sia installato, quindi eseguili nel tuo ambiente piuttosto che in un interprete vuoto.

Leggi i file MATLAB con SciPy

Installa la libreria con pip install scipy, poi chiama scipy.io.loadmat("sample.mat"). Restituisce un dizionario: oltre alle tue variabili contiene le chiavi di metadati __header__, __version__ e __globals__, e ogni variabile MATLAB diventa un array NumPy sotto il suo nome nel workspace, quindi data["measurements"] recupera direttamente quella variabile.

Due opzioni vale la pena conoscere quando le dimensioni non tornano. Passando squeeze_me=True a loadmat si eliminano le dimensioni singleton di MATLAB, così uno scalare torna come scalare, e combinandola con struct_as_record=False puoi raggiungere i campi di uno struct come attributi invece che come elementi di array annidati. Per riscrivere i risultati, scipy.io.savemat("out.mat", {"measurements": data["measurements"]}) produce un MAT-file classico.

Il limite di versione è la restrizione importante: loadmat supporta i formati MAT-file solo fino alla 7.2. Con un file 7.3 segnala il formato come non supportato, perché il contenuto è HDF5: quel file richiede l’approccio della sezione successiva. Se controlli il lato MATLAB, salvare con save data.mat -v7 produce un file che loadmat accetta.

Leggi i file MATLAB 7.3 con h5py

Un file -v7.3 è HDF5 con uno user block MATLAB, quindi pip install h5py è tutto ciò che serve per aprirlo. h5py.File("sample_v73.mat", "r") apre il file in lettura, e list(f.keys()) mostra i gruppi di primo livello: uno per variabile MATLAB più un gruppo #refs# che memorizza i contenuti condivisi di cell e struct.

Leggere f["measurements"][()] materializza il dataset come array NumPy; qui NumPy si limita a convertire i dati, perché è h5py ad aprire il file. Due dettagli di layout contano in pratica. MATLAB scrive gli array in ordine column-major, quindi un dataset 2-D comunemente torna trasposto, e f["measurements"][()].T ripristina l’orientamento MATLAB. I cell array e gli struct arrivano come riferimenti a oggetti HDF5 dentro #refs#, quindi devi dereferenziare ogni voce con f[ref] invece di leggerla direttamente.

Leggi i file MATLAB con mat4py

pip install mat4py ti dà un’API più piccola pensata per i MAT-file classici. Dopo from mat4py import loadmat, la chiamata loadmat("sample.mat") restituisce un dizionario ordinario in cui gli array numerici sono liste Python annidate e gli struct diventano dizionari annidati: comodo quando vuoi i dati come tipi Python puri senza tirare in mezzo NumPy.

Considera mat4py un lettore per i formati classici: non apre i file HDF5 7.3, e le strutture MATLAB profondamente annidate o insolite potrebbero non essere convertite correttamente, quindi non è un sostituto per ogni MAT-file. Verifica la conversione di un file complesso confrontandola con scipy.io prima di basarti su di essa.

Leggi i file MATLAB con la MATLAB Engine API

Quando MATLAB stesso è installato, la sua Engine API per Python è l’opzione con la massima fedeltà. Installare matlabengine con pip (o eseguire l’installer fornito con MATLAB) rende disponibile matlab.engine, che pilota una vera sessione MATLAB dietro le quinte. eng = matlab.engine.start_matlab() avvia quella sessione, eng.load("sample.mat") carica ogni variabile nel workspace dell’engine indipendentemente dalla versione del file, e eng.quit() la chiude quando hai finito. I valori tornano come tipi MATLAB come matlab.double, che NumPy converte con np.asarray.

I compromessi sono pratici piuttosto che legati al formato: l’engine richiede un’installazione MATLAB con licenza e una versione dell’engine corrispondente, la sessione impiega secondi ad avviarsi e non può funzionare in un semplice ambiente Python. È anche per questo che questa sezione mostra le chiamate inline invece che come esempio autonomo: le altre librerie sono la scelta giusta di default quando MATLAB non è già presente sulla macchina.