passing numpy.ndarray from Python to Matlab

188 vues (au cours des 30 derniers jours)
Yochanan Steinberg
Yochanan Steinberg le 13 Mai 2015
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 commentaires
David Garrison
David Garrison le 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
Afraz MEHMOOD CHAUDHRY le 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.

Connectez-vous pour commenter.

Réponse acceptée

David Garrison
David Garrison le 27 Août 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.

Plus de réponses (2)

Bo Li
Bo Li le 13 Mai 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 commentaires
Ernst Kloppenburg
Ernst Kloppenburg le 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
Seth Wagenman le 31 Août 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.

Connectez-vous pour commenter.


Seth Wagenman
Seth Wagenman le 31 Août 2020
Modifié(e) : Seth Wagenman le 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);

Catégories

En savoir plus sur Call Python from MATLAB dans Help Center et File Exchange

Community Treasure Hunt

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

Start Hunting!

Translated by