使用NumPy正确读写Fortran顺序数组的方法。

3

我正在编写一个应用程序,该程序读取一个带有Fortran排序数组的ascii文件,修改值,然后以Fortran顺序将数据写回(以ascii格式)。那么在numpy中正确的方法是什么,如何表示数组是按Fortran顺序排列的,然后以Fortran顺序将数据写回?

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

0.0 1.0 2.0 3.0 4.0 5.0 6.0 7.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')吗?


1
如果 x 已经像 Fortran 数组一样排序,那么在 nditer 中不需要使用 order(默认情况下,它按内存顺序迭代)。 - nneonneo
2个回答

1
这是有效的方法。转置是因为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

1
考虑以下内容:
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 将保留原始排序。

这看起来是正确的。 我的主要问题是我没有意识到 x.shape = (2,2,2) 实际上会改变顺序。我使用的是 order 'F' 创建它。 但是,当我第一次创建数组时,它是一维的,因此顺序不会生效。 因此,使用 .shape = (2,2,2) 更改形状并没有保持 fortran 排序。 - durden2.0
有没有一种方法可以同时创建一个具有形状和顺序的数组?我在API中没有看到这个选项。可能不是很重要,因为我将在所有地方使用视图而不是原始数组。因此,在这种情况下,数据只复制一次,即在创建它并从Python列表复制时。 - durden2.0
不要使用numpy的tofile方法。无论数组在内存中的顺序如何,它始终会写入C顺序(请参阅手册)。 - Sven

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接