我有一个二进制文件,其中包含32位浮点数的密集n*m
矩阵。将它读入Fortran排序的numpy
数组的最有效方法是什么?
该文件的大小为数千兆字节。我可以控制格式,但它必须是紧凑的(即长度大约4*n*m
个字节)并且必须易于从非Python代码生成。
编辑:该方法必须直接生成Fortran排序矩阵(由于数据的大小,我无法创建C有序矩阵然后转换它进入一个单独的Fortran命令副本。)
答案 0 :(得分:12)
NumPy提供fromfile()
来读取二进制数据。
a = numpy.fromfile("filename", dtype=numpy.float32)
将创建一个包含数据的一维数组。要将其作为二维Fortran排序的n x m
矩阵进行访问,您可以对其进行整形:
a = a.reshape((n, m), order="FORTRAN")
[编辑:在这种情况下,reshape()
实际上复制了数据(请参阅注释)。要在没有cpoying的情况下执行此操作,请使用
a = a.reshape((m, n)).T
感谢Joe Kingtion指出这一点。]
但说实话,如果你的矩阵有几千兆字节,我会选择像h5py或PyTables这样的HDF5工具。这两个工具都有FAQ条目,将工具与另一个工具进行比较。我通常更喜欢h5py,虽然PyTables似乎更常用(两个项目的范围略有不同)。
HDF5文件可以使用数据分析中使用的大多数编程语言编写。链接的维基百科文章中的接口列表不完整,例如还有一个R interface。但实际上我不知道你想用哪种语言写数据......
答案 1 :(得分:1)
基本上Numpy将数组存储为平面向量。多维度只是由Numpy迭代器使用的不同视图和步幅创建的错觉。
有关Numpy内部如何运作的详尽但易于理解的说明,请参阅优秀的chapter 19 on The Beatiful Code book。
至少Numpy array()
和reshape()
有一个C('C'),Fortran('F')或保留顺序('A')的参数。
另请参阅问题How to force numpy array order to fortran style?
>>> a = np.arange(12).reshape(3,4) # <- C order by default
>>> a
array([[ 0, 1, 2, 3],
[ 4, 5, 6, 7],
[ 8, 9, 10, 11]])
>>> a[1]
array([4, 5, 6, 7])
>>> a.strides
(32, 8)
>>> a = np.arange(12).reshape(3,4, order='F')
>>> a
array([[ 0, 3, 6, 9],
[ 1, 4, 7, 10],
[ 2, 5, 8, 11]])
>>> a[1]
array([ 1, 4, 7, 10])
>>> a.strides
(8, 24)
此外,您始终可以使用数组的参数T获取其他类型的视图:
>>> a = np.arange(12).reshape(3,4, order='C')
>>> a.T
array([[ 0, 4, 8],
[ 1, 5, 9],
[ 2, 6, 10],
[ 3, 7, 11]])
>>> a = np.arange(12).reshape(3,4, order='F')
>>> a.T
array([[ 0, 1, 2],
[ 3, 4, 5],
[ 6, 7, 8],
[ 9, 10, 11]])
>>> a = np.arange(12).reshape(3,4, order='C')
>>> a
array([[ 0, 1, 2, 3],
[ 4, 5, 6, 7],
[ 8, 9, 10, 11]])
>>> a.strides
(32, 8)
>>> a.strides = (8, 24)
>>> a
array([[ 0, 3, 6, 9],
[ 1, 4, 7, 10],
[ 2, 5, 8, 11]])