首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >嵌套MATLAB结构在DataJoint Python中获取时很难解析。

嵌套MATLAB结构在DataJoint Python中获取时很难解析。
EN

Stack Overflow用户
提问于 2022-05-05 19:59:05
回答 2查看 88关注 0票数 0

在DataJoint Python和DataJoint MATLAB中,我已经将相同的值插入了一个长From属性中。在DataJoint中,它是作为字典插入的,从DataJoint中插入是作为一个结构。使用Python插入的条目在DataJoint中获取时是一个recarray,这是预期的。但是,由于存在嵌套值,这个recarray很难解析。

插入DataJoint Python,用DataJoint Python获取:

代码语言:javascript
复制
{'cat_gt': {'use_cat_gt': 1,
  'cat_gt_params': {'apfilter': ['biquad', 2, 300, 0],
   'gfix': [0.4, 0.1, 0.02],
   'extras': ['prb_fld', 't_miss_ok', 'ap', 'gblcar', 'out_prb_fld']}},
 'process_cluster': 'tiger',
 'clustering_method': 'Kilosort2'}

插入到DataJoint MATLAB中,用DataJoint获取:

代码语言:javascript
复制
rec.array([[(rec.array([[(array([[1.]]), rec.array([[(MatCell([['biquad'],
                                             [2.0],
                                             [300.0],
                                             [0.0]], dtype=object), array([[0.4 ],
                                           [0.1 ],
                                           [0.02]]), MatCell([['prb_fld'],
                                             ['t_miss_ok'],
                                             ['ap'],
                                             ['gblcar'],
                                             ['out_prb_fld']], dtype='<U11'))     ]],
                                  dtype=[('apfilter', 'O'), ('gfix', 'O'), ('extras', 'O')]))]],
                      dtype=[('use_cat_gt', 'O'), ('cat_gt_params', 'O')]), array(['tiger'], dtype='<U5'), array(['Kilosort2'], dtype='<U9'))]],
          dtype=[('cat_gt', 'O'), ('process_cluster', 'O'), ('clustering_method', 'O')])

使用query.fetch(as_dict=True)似乎不能解决这个问题:

代码语言:javascript
复制
[{'preprocess_paramset': rec.array([[(rec.array([[(array([[1.]]), rec.array([[(MatCell([['biquad'],
                                               [2.0],
                                               [300.0],
                                               [0.0]], dtype=object), array([[0.4 ], ...

我可以创建一个递归函数,用于将recarray转换为字典,但是我想知道DataJoint中是否有一个本机方法来获取这个条目并将其转换为一个字典?

谢谢!

EN

回答 2

Stack Overflow用户

发布于 2022-05-05 20:28:05

这是预期的行为。MATLAB结构不等同于python中的字典列表。他们更像numpy.recarrayfetch标志as_dict应用于获取结果的结构,而不是blob内部。

可以编写一个函数将嵌套的recarrays转换为字典。很难使它普遍工作,因为MATLAB结构数组和单元格数组不容易映射到本机Python类型。

票数 0
EN

Stack Overflow用户

发布于 2022-05-07 03:26:34

我不确定数据连接返回的内容是否与从this post加载函数返回的数据类似,但以下是一些代码,至少可以开始清理借用自<3的matlab结构/重新数组。从数据连接中获得干净的往返(因为模型定义在两种语言中是相同的,因此似乎也应该从存储格式返回,但还没有查看内部结构),这将是很好的选择,但同时.

代码语言:javascript
复制
def clean_recarray(data:np.recarray) -> dict:
    '''
    Clean up a recarray into python lists, dictionaries, and
    numpy arrays rather than the sort-of hard to work with numpy record arrays.
    
    Credit to https://stackoverflow.com/a/29126361/13113166
    Args:
        data (:class:`numpy.recarray`): Array to be cleaned!
    Returns:
        dict
    '''
    def _check_keys(d):
        '''
        checks if entries in dictionary are mat-objects. If yes
        todict is called to change them to nested dictionaries
        '''
        for key in d:
            if isinstance(d[key], mat_struct):
                d[key] = _todict(d[key])
            elif _has_struct(d[key]):
                d[key] = _tolist(d[key])
        return d

    def _has_struct(elem):
        """Determine if elem is an array and if any array item is a struct"""
        return isinstance(elem, np.ndarray) and any(isinstance(
                    e, mat_struct) for e in elem)

    def _todict(matobj):
        '''
        A recursive function which constructs from matobjects nested dictionaries
        '''
        d = {}
        for strg in matobj._fieldnames:
            elem = matobj.__dict__[strg]
            if isinstance(elem, mat_struct):
                d[strg] = _todict(elem)
            elif _has_struct(elem):
                d[strg] = _tolist(elem)
            else:
                d[strg] = elem
        return d

    def _tolist(ndarray):
        '''
        A recursive function which constructs lists from cellarrays
        (which are loaded as numpy ndarrays), recursing into the elements
        if they contain matobjects.
        '''
        elem_list = []
        for sub_elem in ndarray:
            if isinstance(sub_elem, mat_struct):
                elem_list.append(_todict(sub_elem))
            elif _has_struct(sub_elem):
                elem_list.append(_tolist(sub_elem))
            else:
                elem_list.append(sub_elem)
        return elem_list
    return _check_keys(data)
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/72132975

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档