web-dev-qa-db-fra.com

"Conversion" des tableaux Numpy en Matlab et inversement

Je cherche un moyen de passer des tableaux NumPy à Matlab. 

J'ai réussi à le faire en stockant le tableau dans une image à l'aide de scipy.misc.imsave, puis en le chargeant à l'aide de imread, mais ceci entraîne bien sûr que la matrice contienne des valeurs comprises entre 0 et 256 au lieu des valeurs «réelles». 

Prendre le produit de cette matrice divisé par 256 et la valeur maximale du tableau NumPy d'origine me donne la matrice correcte, mais j'estime que c'est un peu fastidieux. 

y a-t-il un moyen plus simple?

27
user1444165

Bien sûr, utilisez simplement scipy.io.savemat

Par exemple:

import numpy as np
import scipy.io

x = np.linspace(0, 2 * np.pi, 100)
y = np.cos(x)

scipy.io.savemat('test.mat', dict(x=x, y=y))

De même, il y a scipy.io.loadmat.

Vous chargez ensuite ceci dans matlab avec load test.

Alternativement, comme @JAB l’a suggéré, vous pouvez simplement enregistrer des éléments dans un fichier ASCII délimité par des tabulations (par exemple, numpy.savetxt). Cependant, vous serez limité à 2 dimensions si vous choisissez cette voie. En revanche, ascii est le format d'échange universel. Pratiquement n'importe quoi gérera un fichier texte délimité.

41
Joe Kington

Une solution simple, sans transmettre de données par fichier ou par des bibliothèques externes.

Numpy a une méthode pour transformer ndarrays en liste et les types de données matlab peuvent être définis à partir de listes. Alors, quand peut transformer comme:

np_a = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]])
mat_a = matlab.double(np_a.tolist())

Du matlab au python nécessite plus d'attention. Il n'y a pas de fonction intégrée pour convertir le type directement en listes. Mais nous pouvons accéder aux données brutes, qui ne sont pas façonnées, mais simples. Donc, nous utilisons reshape (pour formater correctement) et transpose (à cause de la manière différente MATLAB et numpy store data). Il est vraiment important de souligner: testez-le dans votre projet, surtout si vous utilisez des matrices avec plus de 2 dimensions. Cela fonctionne pour MATLAB 2015a et 2 dims.

np_a = np.array(mat_a._data.tolist())
np_a = np_a.reshape(mat_a.size).transpose()
7
Juliano ENS

scipy.io.savemat ou scipy.io.loadmat NE FONCTIONNE PAS pour les tableaux matlab --v7.3. Mais le bon côté est que les fichiers matlab --v7.3 sont des ensembles de données hdf5. Ils peuvent donc être lus à l’aide de nombreux outils, notamment numpy.

Pour python, vous aurez besoin de l’extension h5py , qui nécessite l’option HDF5 sur votre système.

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

Il y a quelque temps, j'ai rencontré le même problème et écrit les scripts suivants pour permettre une copie et un collage faciles des tableaux à partir de sessions interactives. Évidemment, ce n’est pratique que pour les petits tableaux, mais j’ai trouvé cela plus pratique que de sauvegarder/charger un fichier à chaque fois:

Matlab -> Python

Python -> Matlab

2
robince

Je ne suis pas sûr que cela compte comme "plus simple", mais j'ai trouvé une solution pour déplacer des données depuis un tableau numpy créé dans un script python appelé par matlab assez rapidement:

dump_reader.py (source python):

import numpy

def matlab_test2():
    np_a    = numpy.random.uniform(low = 0.0, high = 30000.0, size = (1000,1000))
    return np_a

dump_read.m (script matlab):

clear classes
mod = py.importlib.import_module('dump_reader');
py.importlib.reload(mod);

if count(py.sys.path,'') == 0
    insert(py.sys.path,int32(0),'');
end

tic
A = py.dump_reader.matlab_test2();
toc
shape = cellfun(@int64,cell(A.shape));
ls = py.array.array('d',A.flatten('F').tolist());
p = double(ls);
toc
C = reshape(p,shape);
toc

Cela repose sur le fait que matlabs double semble fonctionner efficacement sur les tableaux par rapport aux cellules/matrices. La deuxième astuce consiste à transmettre les données à matlabs double de manière efficace (via le fichier array.array natif de pythons).

P.S. désolé pour le nécropostage mais j'ai beaucoup lutté avec son et ce sujet était l'un des succès les plus proches. Peut-être que cela aide quelqu'un à raccourcir le temps passé à se battre.

P.P.S. testé avec Matlab R2016b + python 3.5.4 (64bit)

1
John Smith