在DataJoint Python和DataJoint MATLAB中,我已经将相同的值插入了一个长From属性中。在DataJoint中,它是作为字典插入的,从DataJoint中插入是作为一个结构。使用Python插入的条目在DataJoint中获取时是一个recarray,这是预期的。但是,由于存在嵌套值,这个recarray很难解析。
插入DataJoint Python,用DataJoint Python获取:
{'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获取:
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)似乎不能解决这个问题:
[{'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中是否有一个本机方法来获取这个条目并将其转换为一个字典?
谢谢!
发布于 2022-05-05 20:28:05
这是预期的行为。MATLAB结构不等同于python中的字典列表。他们更像numpy.recarray。fetch标志as_dict应用于获取结果的结构,而不是blob内部。
可以编写一个函数将嵌套的recarrays转换为字典。很难使它普遍工作,因为MATLAB结构数组和单元格数组不容易映射到本机Python类型。
发布于 2022-05-07 03:26:34
我不确定数据连接返回的内容是否与从this post加载函数返回的数据类似,但以下是一些代码,至少可以开始清理借用自<3的matlab结构/重新数组。从数据连接中获得干净的往返(因为模型定义在两种语言中是相同的,因此似乎也应该从存储格式返回,但还没有查看内部结构),这将是很好的选择,但同时.
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)https://stackoverflow.com/questions/72132975
复制相似问题