passing numpy.ndarray from Python to Matlab

289 visualizzazioni (ultimi 30 giorni)
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 Commenti
David Garrison
David Garrison il 16 Set 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
Afraz MEHMOOD CHAUDHRY il 29 Set 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.

Accedi per commentare.

Risposta accettata

David Garrison
David Garrison il 27 Ago 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.

Più risposte (2)

Bo Li
Bo Li il 13 Mag 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 Commenti
Ernst Kloppenburg
Ernst Kloppenburg il 24 Gen 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
Seth Wagenman il 31 Ago 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.

Accedi per commentare.


Seth Wagenman
Seth Wagenman il 31 Ago 2020
Modificato: Seth Wagenman il 14 Set 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);

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by