Python hdf5storage 正在转置我的数据?
Python hdf5storage is transposing my data?
Python代码:
import h5py
import hdf5storage
from functools import reduce
import numpy as np
from operator import mul
sz = 128,256,512
a = np.random.normal(size=reduce(mul,sz)).reshape(sz)
save_dict = {'data':a}
spath = r"test.mat"
hdf5storage.savemat(spath, mdict=save_dict, append_mat=False,
store_python_metadata=True, format='7.3')
with h5py.File(spath, 'r') as file:
b = np.array(file['data'])
# Reads in the correct shape, but is F-contiguous. Scipy doesn't work with v7.3 files.
c = hdf5storage.loadmat(spath)['data']
创建 a 时,它的形状为 (128,256,512)。但是,当我使用 hdf5storage 将 a 保存到 .mat 文件,然后使用 h5py 将其加载到 b 时,b 被转置为 (512,256,128) 的形状。检查其标志时,两个数组都是 C 连续的。
有什么办法可以防止这种转置的发生吗?我的印象是 hdf5 格式保存行优先。
我再次查看了 abc.h5
中描述的文件:
how to import .mat-v7.3 file using h5py
它是在 Octave 中创建的:
>> A = [1,2,3;4,5,6];
>> B = [1,2,3,4];
>> save -hdf5 abc.h5 A B
使用h5py
:
In [102]: f = h5py.File('abc.h5','r')
In [103]: A = f['A']['value'][:]
In [104]: A
Out[104]:
array([[1., 4.],
[2., 5.],
[3., 6.]])
In [105]: A.shape
Out[105]: (3, 2)
In [106]: A.flags
Out[106]:
C_CONTIGUOUS : True
F_CONTIGUOUS : False
...
In [107]: A.ravel()
Out[107]: array([1., 4., 2., 5., 3., 6.])
所以这是一个转置的 C 序数组。显然这就是 MATLAB 开发人员选择将其矩阵存储在 HDF5 中的方式。
我可以在 numpy 中转置它:
In [108]: At = A.T
In [109]: At
Out[109]:
array([[1., 2., 3.],
[4., 5., 6.]])
In [110]: At.flags
Out[110]:
C_CONTIGUOUS : False
F_CONTIGUOUS : True
....
正常情况下,C 阶数组在转置后变为 F 阶。
使用较旧的 .mat 格式保存的 Octave 矩阵
In [115]: data = io.loadmat('../abc.mat')
In [116]: data['A']
Out[116]:
array([[1., 2., 3.],
[4., 5., 6.]])
In [117]: _.flags
Out[117]:
C_CONTIGUOUS : False
F_CONTIGUOUS : True
因此,转置后的 h5py
数组符合 io.loadmat
已经使用了相当长一段时间的约定。
我没有在 OS 上安装 hdf5storage
。但是根据您的测试,它遵循 io.loadmat
约定 - 正确的形状但 F 顺序。
Python代码:
import h5py
import hdf5storage
from functools import reduce
import numpy as np
from operator import mul
sz = 128,256,512
a = np.random.normal(size=reduce(mul,sz)).reshape(sz)
save_dict = {'data':a}
spath = r"test.mat"
hdf5storage.savemat(spath, mdict=save_dict, append_mat=False,
store_python_metadata=True, format='7.3')
with h5py.File(spath, 'r') as file:
b = np.array(file['data'])
# Reads in the correct shape, but is F-contiguous. Scipy doesn't work with v7.3 files.
c = hdf5storage.loadmat(spath)['data']
创建 a 时,它的形状为 (128,256,512)。但是,当我使用 hdf5storage 将 a 保存到 .mat 文件,然后使用 h5py 将其加载到 b 时,b 被转置为 (512,256,128) 的形状。检查其标志时,两个数组都是 C 连续的。
有什么办法可以防止这种转置的发生吗?我的印象是 hdf5 格式保存行优先。
我再次查看了 abc.h5
中描述的文件:
how to import .mat-v7.3 file using h5py
它是在 Octave 中创建的:
>> A = [1,2,3;4,5,6];
>> B = [1,2,3,4];
>> save -hdf5 abc.h5 A B
使用h5py
:
In [102]: f = h5py.File('abc.h5','r')
In [103]: A = f['A']['value'][:]
In [104]: A
Out[104]:
array([[1., 4.],
[2., 5.],
[3., 6.]])
In [105]: A.shape
Out[105]: (3, 2)
In [106]: A.flags
Out[106]:
C_CONTIGUOUS : True
F_CONTIGUOUS : False
...
In [107]: A.ravel()
Out[107]: array([1., 4., 2., 5., 3., 6.])
所以这是一个转置的 C 序数组。显然这就是 MATLAB 开发人员选择将其矩阵存储在 HDF5 中的方式。
我可以在 numpy 中转置它:
In [108]: At = A.T
In [109]: At
Out[109]:
array([[1., 2., 3.],
[4., 5., 6.]])
In [110]: At.flags
Out[110]:
C_CONTIGUOUS : False
F_CONTIGUOUS : True
....
正常情况下,C 阶数组在转置后变为 F 阶。
使用较旧的 .mat 格式保存的 Octave 矩阵
In [115]: data = io.loadmat('../abc.mat')
In [116]: data['A']
Out[116]:
array([[1., 2., 3.],
[4., 5., 6.]])
In [117]: _.flags
Out[117]:
C_CONTIGUOUS : False
F_CONTIGUOUS : True
因此,转置后的 h5py
数组符合 io.loadmat
已经使用了相当长一段时间的约定。
我没有在 OS 上安装 hdf5storage
。但是根据您的测试,它遵循 io.loadmat
约定 - 正确的形状但 F 顺序。