%% Core_py2matlab
%
% How to configure Python in MATLAB 2015b (on a Windows Box):
%
% # Download Python 3.4 from <python.org/downloads/>. Ensure that the
% 32-bit or 64-bit version of Python is consistent with MATLAB.
% # Update the Windows Path Environment Variable to include the Python path
% and the _PythonXX\Scripts_ path.
%
% Notes: 
%
% # Data structures that are more than 2 dimensions are not handled.
% # Data structures must be fully defined, i.e. no empty brackets [].
function matlabData = py2matlab(pythonData)
%%%
% convert Python into MATLAB
format long
pd = py.importlib.import_module('pandas');
np = py.importlib.import_module('numpy');

% mp=py.importlib.import_module('mat4py');

matlabData = recursiveFunPy2Matlab(pythonData);
%%%
% Matrices of numbers are converted into cells, so another function will
% reformat these into matrices.
matlabData = recursiveFunCell2MatCheck(matlabData);
%% pythonConversion
% <matlab:doc('handling-data-returned-from-python') data from Python>
    function matlabData = pythonConversion(pyData)
        pyType = class(pyData);
        switch pyType
            case {'py.str','py.unicode'}
                matlabData = char(pyData);
            case 'py.bytes'
                matlabData = uint8(pyData);
            case {'py.int','py.long','py.array.array'}
                matlabData = double(pyData);
            case {'py.list','py.tuple'}
                matlabData = cell(pyData);
            case 'py.dict'
                matlabData = struct(pyData);
            case 'py.numpy.ndarray'
                pyData=pyData.tolist;
                matlabData = pythonConversion(pyData);
            case 'py.pandas.core.frame.DataFrame'
                 pyData=pyData.values;
                 matlabData = pythonConversion(pyData);
            otherwise
                matlabData = pyData;
        end
    end
%% recursiveFunPy2Matlab
% Loops through the Python data types and converts them into MATLAB data
% types
    function matlabData = recursiveFunPy2Matlab(pyData)
        matlabData = pythonConversion(pyData);
        matlabType = class(matlabData);
        mynum = numel(matlabData);
        switch matlabType
            case 'cell'
                for i = 1:mynum
                    matlabData{i} = recursiveFunPy2Matlab(matlabData{i});
                end
            case 'struct'
                for i = 1:mynum
                    myfields = fieldnames(matlabData(i));
                    for j = 1:numel(myfields)
                        matlabData(i).(myfields{j}) = recursiveFunPy2Matlab(matlabData(i).(myfields{j}));
                    end
                end
        end
    end
%% recursiveFunCell2MatCheck
% A second loop through the data structure identifies numeric matrices
% stored as cells
    function mydata = recursiveFunCell2MatCheck(mydata)
        myType = class(mydata);
        mynum = numel(mydata);
        switch myType
            case 'cell'
                if iscellstr(mydata)
                    return
                elseif all(cellfun(@isnumeric,mydata(:)))
                    % This is the key condition. A cell full of numbers
                    % will be converted into a matrix.
                    try
                        mydata = cell2mat(mydata);
                    catch
                        %do nothing
                    end
                else
                    for i = 1:mynum
                        mydata{i} = recursiveFunCell2MatCheck(mydata{i});
                    end
                    if all(cellfun(@isnumeric,mydata(:)))
                        % This is to handle 2D matrices. Anything that has
                        % more than 2 dimensions will be flattened to 2D.
                        try
                            mydata = cell2mat(transpose(mydata));
                        catch
                            %do nothing
                        end
                    end
                end
            case 'struct'
                for i = 1:numel(mydata)
                    myfields = fieldnames(mydata(i));
                    for j = 1:numel(myfields)
                        mydata(i).(myfields{j}) = recursiveFunCell2MatCheck(mydata(i).(myfields{j}));
                    end
                end
        end
    end

if iscell(matlabData)    %如果是cell套cell，转化为不含cell的的cell数组，如果输入的数据是dataframe类型，则转化为table
    m_mldt=numel(matlabData);%获取行数
  
    n_mldt=numel(matlabData{1});%#获取列数    

    for  i=1:m_mldt
        for j=1:n_mldt
            tr{i,j}=matlabData{i}{j};
        end
    end
    
      pyType = class(pythonData);
        switch pyType
           case 'py.pandas.core.frame.DataFrame'  %如果输入数据是DataFrame，则转化为table
%                x=pythonData.select_dtypes(include='number')
               t_name=cell(pythonData.columns.values.tolist());%获取表头名称
               t_namec=cellfun(@char,t_name,'UniformOutput',false);
               matlabData = cell2table(tr,'VariableNames',t_namec );
            otherwise %否则取之前处理后的结果
               matlabData=tr;
        end
        
   elseif isa(matlabData,'double')
          pyType = class(pythonData);
        switch pyType
           case 'py.pandas.core.frame.DataFrame'  %如果输入数据是DataFrame，则转化为table
               t_name=cell(pythonData.columns.values.tolist());%获取表头名称
               t_namec=cellfun(@char,t_name,'UniformOutput',false);
               matlabData = array2table(tr,'VariableNames',t_namec );
        end
    elseif  isstruct(matlabData)
        matlabData=struct2table(matlabData);
   
end

if istable(matlabData)
    
end

end
