2

使用 SciPy 和 MATLAB,我无法重建数组以匹配使用 scipy.io.loadmat() 加载的 MATLAB 单元数组给出的内容。

例如,假设我在 MATLAB 中创建了一个包含一对双精度数组的单元格,然后使用 scipy.io 加载它(我正在使用 SPM 与 pynifti 等进行成像分析)

MATLAB

>> onsets{1} = [0 30 60 90]
>> onsets{2} = [15 45 75 105]

Python

>>> import scipy.io as scio
>>> mat = scio.loadmat('onsets.mat')
>>> mat['onsets'][0]
array([[[ 0 30 60 90]], [[ 15  45  75 105]]], dtype=object)

>>> mat['onsets'][0].shape

(2,)

我的问题是:为什么这个 numpy 数组的形状是 (2,) 而不是 (2,1,4)?在现实生活中,我正在尝试使用 Python 解析日志文件并构建这些起始单元格数组,因此我希望能够从头开始构建它们。

当我尝试从打印输出构建相同的数组时,我得到了不同的形状:

>>> new_onsets = array([[[ 0, 30, 60, 90]], [[ 15,  45,  75, 105]]], dtype=object)
array([[[0, 30, 60, 90]],

       [[15, 45, 75, 105]]], dtype=object)

>>> new_onsets.shape
(2,1,4)

不幸的是,形状(单元格数组中的双精度向量)是在上游规范中编码的,所以我需要能够以这种格式准确地保存它。当然,这没什么大不了的,因为我可以在 MATLAB 中编写解析器,但是弄清楚发生了什么并增加我对 numpy 的[微不足道] 知识会很好。

4

3 回答 3

1

来自 scipy 邮件列表的 Travis 回应说,构建它的正确方法是首先创建结构,然后填充数组:

http://article.gmane.org/gmane.comp.python.scientific.user/31760

> 您可以使用以下方法构建您之前看到的内容:
>
> new_onsets = empty((2,), dtype=object)
> new_onset[0] = 数组([[0, 30, 60, 90]])
> new_onsets[1] = 数组([[15, 45, 75, 105]])
于 2012-05-14T15:44:45.540 回答
1

这是我个人觉得在 python 中有点烦人的事情之一。这是因为loadmat自动“挤压”尺寸。

默认情况下,squeeze_me=True 所以你已经看到你得到这个:

>>> x = sio.loadmat('mymat.mat',squeeze_me=True)
>>> y = x['onsets']
>>> y.shape
(2,)

如果您使用 loadmat 并将squeeze_me 设置为False,那么您不会挤出一维:

>>> a = sio.loadmat('mymat.mat',squeeze_me=False)
>>> a
>>> b = a['onsets']
>>> b.shape
(1, 2)

也就是说,我一生都无法弄清楚如何让另一个维度显示(即b.shape = (1,2,4))对于像“onsets”这样的单元格数组。我只能为非细胞普通的香草 MATLAB 数组获得它

onset_array = [onsets{1}; onsets{2}];
于 2012-05-10T22:51:21.033 回答
1

我认为这里的问题是单元数组并不是真正的数组,这就是scio.loadmat加载onsets.matobject数组的原因。

在这里,您的元胞数组可以简化为一个普通的 shape 数组(2,1,4),但是如果您的数据看起来像:

>> onsets{1} = {0 30 60 'bob'}
>> onsets{2} = {15 45 75 'fred'}

我不确定最好的解决方案是什么,但如果你知道你的数据是一个数组,你应该在保存到 Matlab 之前或在使用 Scipy 加载之后转换为普通数组。

编辑:理论上,上面的示例单元格数组可以转换为 numpy结构化数组,但请注意,单元格数组通常不是这样,因为列不必是相同的数据类型。表示任意数据类型列表的逻辑方法是使用 Python 列表(或此处的列表数组),这就是loadmat返回的内容。

编辑 2:按照 Erik Kastman 的建议,修复元胞数组语法。

于 2012-05-11T15:42:52.750 回答