I have a series of numpy arrays that I want to save in a .mat file so that I can plot the data later. (I don't want to use Pickle because my actual program is much more complicated and has more than 2 arrays.) My MWE is:
import numpy as np
import mat4py as m4p
x = np.array([1,20,0.4,0.5,9,8.8])
y = np.array([0.3,0.6,1,1,0.01,0.7])
data = {'x': x,
'y': y}
m4p.savemat('datafile.mat', data)
but I get an error ValueError: Only dicts, two dimensional numeric, and char arrays are currently supported.
What does this mean and how can I fix this?
In [853]: from scipy import io
In [854]: x = np.array([1,20,0.4,0.5,9,8.8])
...: y = np.array([0.3,0.6,1,1,0.01,0.7])
...:
In [855]: data={'x':x, 'y':y}
In [856]: io.savemat('test.mat',data)
In [857]: io.loadmat('test.mat')
Out[857]:
{'__globals__': [],
'__header__': b'MATLAB 5.0 MAT-file Platform: posix, Created on: Sun Nov 27 09:30:35 2016',
'__version__': '1.0',
'x': array([[ 1. , 20. , 0.4, 0.5, 9. , 8.8]]),
'y': array([[ 0.3 , 0.6 , 1. , 1. , 0.01, 0.7 ]])}
For MATLAB compatibility the arrays have been turned into 2d orderF arrays.
h5py is another option. Newer Matlab versions use the HDF5 format, providing greater compatibility with other languages.
np.savez can save a dictionary of arrays without modifying them:
In [881]: data={'x':x, 'y':y,'xy':np.array((x,y))}
In [882]: np.savez('test',**data)
In [883]: D=np.load('test.npz')
In [884]: D.keys()
Out[884]: ['y', 'x', 'xy']
In [885]: D['xy']
Out[885]:
array([[ 1.00000000e+00, 2.00000000e+01, 4.00000000e-01,
5.00000000e-01, 9.00000000e+00, 8.80000000e+00],
[ 3.00000000e-01, 6.00000000e-01, 1.00000000e+00,
1.00000000e+00, 1.00000000e-02, 7.00000000e-01]])
D is an NPZFile object, which is a lazy loader. So it does not dump all the arrays directly into memory. You access them by key name.
You have to convert numpy arrays into python lists.
You can create x and y like:
x = [1,20,0.4,0.5,9,8.8]
y = [0.3,0.6,1,1,0.01,0.7]
Now data will contain python lists and m4p.savemat('datafile.mat', data) will work.
Edit:
If you need to work with numpy arrays, you can convert them on-the-fly when creating data as follows:
data = {'x' : x.tolist(), 'y' : y.tolist()}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With