【问题标题】:Proper way to read/write fortran order array with numpy使用 numpy 读取/写入 fortran 顺序数组的正确方法
【发布时间】:2013-07-21 16:55:57
【问题描述】:

我正在编写一个应用程序,它读取带有 fortran 排序数组的 ascii 文件,修改值,然后在 ascii 中写回该数据(按 fortran 顺序)。将这个数组读入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')吗?

【问题讨论】:

  • 如果 x 已经像 Fortran 数组一样排序,则 ordernditer 中不需要(默认情况下,按内存顺序迭代)。

标签: python arrays numpy


【解决方案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

【讨论】:

    【解决方案2】:

    考虑以下几点:

    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')
    

    这里,xf2x2x2 上的 x 的 Fortran 有序视图。你可以修改它,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) 实际上会改变顺序。我用命令“F”创建了它。但是,当我第一次创建数组时,它是一维的,因此顺序不会生效。因此,使用 .shape = (2,2,2) 更改形状并不能保持 fortran 顺序。
    • 有没有办法同时创建一个形状和顺序的数组?我在 API 中没有看到这一点。可能没什么大不了的,因为我只会在任何地方使用视图,而不是原始数组。因此,在这种情况下,数据不会被复制两次,仅在创建它并从 python 列表复制时复制一次。
    • 不要使用 numpy tofile。无论数组在内存中的顺序如何,它总是写入 C 顺序(参见手册)。
    猜你喜欢
    • 2011-10-18
    • 2020-02-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-04-18
    • 2017-10-28
    • 2011-12-03
    相关资源
    最近更新 更多