如何在Matlab数据结构中使用多维数组从Python创建Matlab文件?

如何在Matlab数据结构中使用多维数组从Python创建Matlab文件?,python,matlab,numpy,Python,Matlab,Numpy,我正在尝试从Python创建一个Matlab文件(*.mat),该文件包含如下所示的Matlab数据结构: s.key1 where key1 is an array of values s.key2 where key2 is an array of 1D arrays s.key3 where key3 is an array of 2D arrays 如果我使用savemat和字典,Matlab输出是一个单元数组,而不是Matlab数据结构 我试过使用 np.core.records

我正在尝试从Python创建一个Matlab文件(*.mat),该文件包含如下所示的Matlab数据结构:

s.key1 where key1 is an array of values
s.key2 where key2 is an array of 1D arrays 
s.key3 where key3 is an array of 2D arrays 
如果我使用savemat和字典,Matlab输出是一个单元数组,而不是Matlab数据结构

我试过使用

np.core.records.fromarrays(data_list, names=q_keys)
但这似乎不适用于具有2D阵列的关键点。我有2D和3D阵列,需要在Matlab结构中与现有文件格式兼容。在Python中有没有实现这一点的方法


谢谢

这是一个尝试:

In [292]: dt = np.dtype([('key1',int),('key2',int, (3,)),('key3',object)])
In [293]: arr = np.zeros((5,), dt)
In [294]: arr
Out[294]: 
array([(0, [0, 0, 0], 0), (0, [0, 0, 0], 0), (0, [0, 0, 0], 0),
       (0, [0, 0, 0], 0), (0, [0, 0, 0], 0)],
      dtype=[('key1', '<i8'), ('key2', '<i8', (3,)), ('key3', 'O')])
In [295]: arr['key1']=np.arange(5)
In [296]: arr['key2']=np.arange(15).reshape(5,3)
In [302]: arr['key3']=[1,np.arange(5),np.ones((2,3),int),'astring',[['a','b']]]
In [303]: io.savemat('test.mat', {'astruct':arr})
回到
ipython

In [304]: d = io.loadmat('test.mat')
In [305]: d
Out[305]: 
{'__header__': b'MATLAB 5.0 MAT-file Platform: posix, Created on: Wed Jun  6 15:36:23 2018',
 '__version__': '1.0',
 '__globals__': [],
 'astruct': array([[(array([[0]]), array([[0, 1, 2]]), array([[1]])),
         (array([[1]]), array([[3, 4, 5]]), array([[0, 1, 2, 3, 4]])),
         (array([[2]]), array([[6, 7, 8]]), array([[1, 1, 1],
        [1, 1, 1]])),
         (array([[3]]), array([[ 9, 10, 11]]), array(['astring'], dtype='<U7')),
         (array([[4]]), array([[12, 13, 14]]), array([['a', 'b']], dtype='<U1'))]],
       dtype=[('key1', 'O'), ('key2', 'O'), ('key3', 'O')])}
[304]中的
:d=io.loadmat('test.mat'))
In[305]:d
Out[305]:
{“头文件”:b'MATLAB 5.0 MAT文件平台:posix,创建日期:Wed Jun 6 15:36:23 2018',
“\uuuuu版本:”1.0“,
“\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu,
'astruct':数组([[(数组([[0]])、数组([[0,1,2]])、数组([[1]]),
(数组([[1]]),数组([[3,4,5]]),数组([[0,1,2,3,4]]),
(数组([[2]])、数组([[6,7,8]])、数组([[1,1,1]],
[1, 1, 1]])),

(array([[3]])、array([[9,10,11]])、array(['astring'])、dtype='根据hpaulj提供的指导,我开发了以下函数,该函数从对象列表创建了一个结构

    def listobj2struct(list_in):
    """Converts a list of objects to a structured array.

    Parameters
    ----------
    list_in: list
        List of objects

    Returns
    -------
    struct: np.array
        Structured array
    """

    # Create data type for each variable in object
    keys = list(vars(list_in[0]).keys())
    data_type = []
    for key in keys:
        data_type.append((key, list))

    # Create structured array based on data type and length of list
    dt = np.dtype(data_type)
    struct = np.zeros((len(list_in),), dt)

    # Populate the structure with data from the objects
    for n, item in enumerate(list_in):
        new_dict = vars(item)
        for key in new_dict:
            struct[key][n] = new_dict[key]

    return struct
为了完成从复杂的对象嵌套中创建Matlab文件所需的工作,我还编写了以下函数。也许这将帮助其他面临类似任务的人。可能有更好的方法,但这对我很有用

    def obj2dict(obj):
    """Converts object variables to dictionaries. Works recursively to all levels of objects.

    Parameters
    ----------
    obj: object
        Object of some class

    Returns
    -------
    obj_dict: dict
        Dictionary of all object variables
    """

    obj_dict = vars(obj)
    for key in obj_dict:
        # Clean out NoneTypes
        if obj_dict[key] is None:
            obj_dict[key] = []
        # If variable is another object convert to dictionary recursively
        elif str(type(obj_dict[key]))[8:13] == 'Class':
            obj_dict[key]=obj2dict(obj_dict[key])

    return obj_dict


def listobj2dict(list_in):
    """Converts list of objects to list of dictionaries. Works recursively to all levels of objects.

    Parameters
    ----------
    obj: object
        Object of some class

    Returns
    -------
    new_list: list
        List of dictionaries
    """
    new_list = []
    for obj in list_in:
        new_list.append(obj2dict(obj))
    return new_list


def listdict2struct(list_in):
    """Converts a list of dictionaries to a structured array.

    Parameters
    ----------
    list_in: list
        List of dictionaries

    Returns
    -------
    struct: np.array
        Structured array
    """

    # Create data type for each variable in object
    keys = list(list_in[0].keys())
    data_type = []
    for key in keys:
        data_type.append((key, list))

    # Create structured array based on data type and length of list
    dt = np.dtype(data_type)
    struct = np.zeros((len(list_in),), dt)

    # Populate the structure with data from the objects
    for n, item in enumerate(list_in):
        new_dict = item
        for key in new_dict:
            struct[key][n] = new_dict[key]

    return struct
    def obj2dict(obj):
    """Converts object variables to dictionaries. Works recursively to all levels of objects.

    Parameters
    ----------
    obj: object
        Object of some class

    Returns
    -------
    obj_dict: dict
        Dictionary of all object variables
    """

    obj_dict = vars(obj)
    for key in obj_dict:
        # Clean out NoneTypes
        if obj_dict[key] is None:
            obj_dict[key] = []
        # If variable is another object convert to dictionary recursively
        elif str(type(obj_dict[key]))[8:13] == 'Class':
            obj_dict[key]=obj2dict(obj_dict[key])

    return obj_dict


def listobj2dict(list_in):
    """Converts list of objects to list of dictionaries. Works recursively to all levels of objects.

    Parameters
    ----------
    obj: object
        Object of some class

    Returns
    -------
    new_list: list
        List of dictionaries
    """
    new_list = []
    for obj in list_in:
        new_list.append(obj2dict(obj))
    return new_list


def listdict2struct(list_in):
    """Converts a list of dictionaries to a structured array.

    Parameters
    ----------
    list_in: list
        List of dictionaries

    Returns
    -------
    struct: np.array
        Structured array
    """

    # Create data type for each variable in object
    keys = list(list_in[0].keys())
    data_type = []
    for key in keys:
        data_type.append((key, list))

    # Create structured array based on data type and length of list
    dt = np.dtype(data_type)
    struct = np.zeros((len(list_in),), dt)

    # Populate the structure with data from the objects
    for n, item in enumerate(list_in):
        new_dict = item
        for key in new_dict:
            struct[key][n] = new_dict[key]

    return struct