Python 用numpy读写fortran顺序数组的正确方法

Python 用numpy读写fortran顺序数组的正确方法,python,arrays,numpy,Python,Arrays,Numpy,我正在编写一个应用程序,该应用程序读取带有fortran顺序数组的ascii文件,修改值,然后将数据以ascii(fortran顺序)写回。将此数组读入numpy的正确方法是什么,表示数组是按fortran顺序的, 然后以fortran顺序写回数据 假设我有一个包含以下ascii文本的文件: 0.01.02.03.04.05.06.07.0 这些数字表示以fortran顺序编写的2x2x2数组 ascii格式比上面的要复杂一些。但是,可以说,该格式并不真正适合使用任何自动numpy ascii加

我正在编写一个应用程序,该应用程序读取带有fortran顺序数组的ascii文件,修改值,然后将数据以ascii(fortran顺序)写回。将此数组读入numpy的正确方法是什么,表示数组是按fortran顺序的, 然后以fortran顺序写回数据

假设我有一个包含以下ascii文本的文件:

0.01.02.03.04.05.06.07.0

这些数字表示以fortran顺序编写的2x2x2数组

ascii格式比上面的要复杂一些。但是,可以说,该格式并不真正适合使用任何自动numpy ascii加载程序,如
numpy.loadtxt

我正在执行与以下类似的行来创建数组:

x=numpy.array([0.0,1.0,2.0,3.0,4.0,5.0,6.0,7.0],order='F')

我知道这是高效的,并且会进行大量额外的数据复制等。不过,我更担心订单


所以,在这一点上,我认为x在内存中的顺序就像fortran数组一样。现在,当我导出此数组时,是否应该使用
numpy.nditer(x,order='F')

考虑以下几点:

In [11]: x = numpy.array([0.0, 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0])

In [12]: xf = x.reshape((2, 2, 2), order='F')
这里,
xf
2x2x2
Fortran顺序视图,位于
x
上。您可以修改它,
x
将相应地更改:

In [22]: xf[0,:,1] = [11, 12]

In [23]: x
Out[23]: array([  0.,   1.,   2.,   3.,  11.,   5.,  12.,   7.])

导出
x
将保留原始顺序。

以下是有效方法。换位是围绕着numpy tofile()只知道C顺序这一事实进行的

import numpy as np
file_path = 'C:/Temp/arr.txt'
x = np.array([0.0, 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0])
xf = x.reshape((2, 2, 2), order='F')
xf.T.tofile(file_path, sep=' ') # T is transpose, so it gets written in correct order
xn = np.fromfile(file_path, sep=' ')
xnr = np.reshape(xn, (2,2,2),order='F')
assert (xf==xnr).all()

# show the transpose is necessary
xf.tofile(file_path, sep=' ') # no .T, write in wrong order
xn = np.fromfile(file_path, sep=' ')
xnr = np.reshape(xn, (2,2,2),order='F')
assert (xf==xnr).all()==False

如果
x
已经像Fortran数组一样排序,
nditer
中不需要
order
(默认情况下,该命令按内存顺序迭代)。这看起来是正确的。我的主要问题是我没有意识到做
x.shape=(2,2,2)
实际上改变了顺序。我用命令“F”创建了它。但是,当我第一次创建数组时,它是一维的,因此顺序不会生效。因此,使用
.shape=(2,2,2)
更改形状并不能保持fortran的顺序。有没有办法同时创建一个具有形状和顺序的数组?我在API中没有看到这一点。可能没什么大不了的,因为我只是到处使用视图,而不是原始数组。因此,在本例中,数据不会被复制两次,在创建数据和从python列表复制数据时只复制一次。无论数组在内存中的顺序是什么,它总是写入C顺序(请参阅手册)。