我猜测您之前的问题是由于现在的numpy.array
从子列表或数组的列表中创建数组引起的。
您注意到markerList
已按预期保存,并且单元格大小不同。
请尝试:
np.array(markerList)
看一下它的形状和数据类型。我猜它会是一个1d数组 (200,),且数据类型为object。
np.array(finalStack)
另一方面,它可能会保存3D数组。"savemat"被设置为保存numpy数组,而不是Python字典和列表——毕竟,它正在与MATLAB通信,而在那里,所有东西都曾经是2D矩阵。MATLAB单元格可以概括这一点;它们更像是dtype对象的2D numpy数组。经常出现从大小统一的元素创建对象数组的问题。通常的解决方案是创建所需大小(例如(200,))和对象类型的“空”数组,并将子数组加载到其中。
https://dev59.com/KZnga4cB1Zd3GeqPaZA-#38776674
=============
我来演示一下。创建3个数组,其中2个大小相同,第三个不同:
In [59]: from scipy import io
In [60]: A=np.ones((40,2))
In [61]: B=np.ones((40,2))
In [62]: C=np.ones((30,2))
保存两个列表,一个只有两个数组,另一个包含全部三个:
In [63]: io.savemat('test.mat', {'AB':[A,B],'ABC':[A,B,C]})
加载它回来;我可以在octave
中完成这个操作:
In [65]: D=io.loadmat('test.mat')
In [66]: D.keys()
Out[66]: dict_keys(['ABC', '__header__', 'AB', '__globals__', '__version__'])
ABC
是一个有3个元素的2D数组
In [68]: D['ABC'].shape
Out[68]: (1, 3)
In [71]: D['ABC'][0,0].shape
Out[71]: (40, 2)
但是
AB
已经被转换成了一个三维数组:
In [69]: D['AB'].shape
Out[69]: (2, 40, 2)
In [70]: np.array([A,B]).shape
Out[70]: (2, 40, 2)
如果我改为使用一个一维对象数组来保存A和B,则它会被保留:
In [72]: AB=np.empty((2,),object)
In [73]: AB[...]=[A,B]
In [74]: AB.shape
Out[74]: (2,)
In [75]: io.savemat('test.mat', {'AB':AB,'ABC':[A,B,C]})
In [76]: D=io.loadmat('test.mat')
In [77]: D['AB'].shape
Out[77]: (1, 2)
In [78]: D['AB'][0,0].shape
Out[78]: (40, 2)
一个好的替代方案是将数组保存为字典的项。
io.savemat('test.mat',{'A':A, 'B':B, 'C':C})
鉴于将MATLAB结构体转换为numpy结构体并返回的困难,最好保持简单扁平化的结构,而不是创建复合对象在两边都有用。
===============
我安装了 Octave。加载这个 test.mat 文件:
Octave
。
io.savemat('test.mat', {'AB':AB,'ABs':[A,B]})
提供
>> whos
Variables in the current scope:
Attr Name Size Bytes Class
==== ==== ==== ===== =====
AB 1x2 1280 cell
ABs 2x40x2 1280 double
一个对象数据类型的数组被保存为Matlab的cell;其他数组被保存为Matlab矩阵。(我需要回顾之前的答案才能想起Matlab结构的等效表示)。
scipy.io.savemat
作为保存Python工作空间的通用库?因为如果是后者,有更好的替代方案。 - Tasos Papastylianousavemat
保存一个形状为 (200,40,2) 的数组到一个期望形状为 (20,) 的 (40,2) 数组的位置不会有问题。如果我的诊断正确,那么这是因为 NumPy 将一组数组转换为一个数组时出现了问题。 - hpaulj