passing numpy.ndarray from Python to Matlab
195 views (last 30 days)
Show older comments
Yochanan Steinberg
on 13 May 2015
Commented: Afraz MEHMOOD CHAUDHRY
on 29 Sep 2020
Hi,
Using the MATLAB engine for Python, I've succeeded in calling and passing scalar data from Python to my MATLAB function, however when trying to pass numpy.ndarray data from Python to MATLAB, the following error is returned:
File "C:\Python27\lib\site-packages\matlab\engine\matlabengine.py", line 74, in __call__
out=_stdout, err=_stderr)
TypeError: unsupported data type numpy.ndarray
Any suggestions? Thanks, Yochanan
2 Comments
David Garrison
on 16 Sep 2020
Yochanan,
Python 3.8 is not supported by R2020a. You would either have to use Python 3.7 or upgrade to MATLAB R2020b which supports Python 3.8.
Thanks, Dave
Afraz MEHMOOD CHAUDHRY
on 29 Sep 2020
Well , I have python 3.7 version but still having problem in calling matlab. The same error I get when I pass arrays from python to matlab using function in python.
Accepted Answer
David Garrison
on 27 Aug 2020
Beginning in MATLAB R2018b, Python functions that accept numpy arrays may also accept MATLAB arrays without explicit conversion. When necessary, a numpy array can be created explicitly from a MATLAB array. For example, if you have a supported version of Python that is installed with the numpy library, you can do the following:
>> x = rand(2,2); % MATLAB array
>> y = py.numpy.array(x); % numpy array
y =
Python ndarray:
0.5943 0.8064
0.6133 0.1372
Use details function to view the properties of the Python object.
Use double function to convert to a MATLAB array.
Also beginning in MATLAB R2018b, it is possible to convert numeric numpy arrays returned from Python into MATLAB arrays. For example:
>> y = py.numpy.random.random([int32(2), int32(2)]) % numpy array
y =
Python ndarray:
0.5943 0.8064
0.6133 0.1372
Use details function to view the properties of the Python object.
Use double function to convert to a MATLAB array.
>> x = 2*double(y) % MATLAB array
x =
1.1885 1.6129
1.2266 0.2744
See the MATLAB documentation on Passing Matrices and Multidimensional Arrays for additional Information.
0 Comments
More Answers (2)
Bo Li
on 13 May 2015
Besides scalar data from Python, MATLAB Engine for Python also support passing MATLAB Arrays as Python variables:
For example:
>>>import matlab.engine
>>>eng = matlab.engine.start_matlab()
>>>A = matlab.double([1.,2.,3.])
>>>eng.sqrt(A)
5 Comments
Ernst Kloppenburg
on 24 Jan 2020
Would you, Bo Li, please add the following as a requirement for future development of the MATLAB Engine for Python:
support numpy.ndarray as input to matlab.double()
Seth Wagenman
on 31 Aug 2020
Doug Bergman, I give an example below where one of the dimensions of the matrix is not hard coded in MATLAB. It is a three-dimensional coordinate transformation so that dimension is hard coded but it need not be if you are working in arbitrary dimensional space and can write code to handle that.
Seth Wagenman
on 31 Aug 2020
Edited: Seth Wagenman
on 14 Sep 2020
The following answer is about a numpy array created in Python, not in MATLAB. The Python module pymatmap3d was something like:
from pymap3d import ecef2eci
from datetime import datetime as dt
from datetime import timedelta as td
from pytz import UTC
from numpy import full, array, hstack
def matlab_datenum_to_datetime(matlab_decimal_datenum):
PYTHON_TO_MATLAB_CORRECTION_CONSTANT = td(days=366)
whole_days = [dt.fromordinal(int(date)) for date in matlab_decimal_datenum]
remainder_days = [number%1 for number in matlab_decimal_datenum]
fractional_days_uncorrected = [td(days=remainder) for remainder in remainder_days]
fractional_days = []
for day in range(len(fractional_days_uncorrected)):
next_fractional_uncorrected_day = fractional_days_uncorrected[day]
fractional_days.append(next_fractional_uncorrected_day - PYTHON_TO_MATLAB_CORRECTION_CONSTANT)
def transform_ecef_to_eci(x_ecef, y_ecef, z_ecef, times_vector):
length = len(times_vector)
xf = full(length, x_ecef)
yf = full(length, y_ecef)
zf = full(length, z_ecef)
times_whole, times_fractional = matlab_datenum_to_datetime(times_vector)
times = [dt(time.year, time.month, time.day, tzinfo=UTC) for time in times_whole]
for time_point in range(length):
times[time_point] += times_fractional[time_point]
x, y, z = ecef2eci(xf, yf, zf, times)
return array(hstack((x, y, z))).reshape((length, 3)).T
This produces a length x 3 numpy ndarray and the following MATLAB code turns that into a matrix:
[time_dimension, ~] = size(ECEF_x, 1);
ECEF_repeated_x = repmat(ECEF_x, time_dimension, 1);
ECEF_repeated_y = repmat(ECEF_y, time_dimension, 1);
ECEF_repeated_z = repmat(ECEF_z, time_dimension, 1);
datenum_times = datenum(MATLAB_datetime_array);
ECI_python_object = ...
py.matmap3d.transform_ecef_to_eci(ECEF_repeated_x, ECEF_repeated_y, ECEF_repeated_z, datenum_times);
returned_numpy_data = double(ECI_python_object.data(:));
ECI_x = returned_numpy_data(:, 1);
ECI_y = returned_numpy_data(:, 2);
ECI_z = returned_numpy_data(:, 3);
1 Comment
Seth Wagenman
on 31 Aug 2020
If using conda environment to install pymap3d, you will need to follow these instructions to make it load: https://www.mathworks.com/matlabcentral/answers/443558-matlab-crashes-when-using-conda-environment-other-than-base#answer_486374
See Also
Categories
Find more on Call Python from MATLAB in Help Center and File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!