将numpy数组保存为二进制文件,以便从FORTRAN中读取

时间:2016-06-19 09:29:07

标签: python numpy fortran

我有一系列numpy数组,我需要将这些numpy数组保存在一个循环中,作为原始二进制float32(没有任何头信息),需要从FORTRAN读取。

import numpy as np
f=open('test.bin','wb+')
for i in range(0,10):
    np_data=np.random.rand(10,5)
    fortran_data=np.asfortranarray(np_data,'float32')
  fortran_data.tofile(f)

f.close()

这是正确的方法,以便我可以正确地从FORTRAN读取在python中创建的这个二进制文件。您的建议将受到高度赞赏

2 个答案:

答案 0 :(得分:3)

您编写的代码几乎是正确的,但.tofile方法始终按C顺序写入向量。我不知道为什么np.asfortranarray()在二进制文件中写入时会避免这种情况,但我测试过,不幸的是我们需要在写入之前转换矩阵,以便在Fortran中正确读取而不需要任何其他关注(这意味着在Fortran中)你可以给出实际的矩阵维度而不需要任何转置)。 下面的代码用3D矩阵(我通常需要使用)来说明我的意思:

a = np.arange(1,10*3*4+1)
b = a.reshape(10,12,order='F')
array([[  1,  11,  21,  31,  41,  51,  61,  71,  81,  91, 101, 111],
   [  2,  12,  22,  32,  42,  52,  62,  72,  82,  92, 102, 112],
   [  3,  13,  23,  33,  43,  53,  63,  73,  83,  93, 103, 113],
   [  4,  14,  24,  34,  44,  54,  64,  74,  84,  94, 104, 114],
   [  5,  15,  25,  35,  45,  55,  65,  75,  85,  95, 105, 115],
   [  6,  16,  26,  36,  46,  56,  66,  76,  86,  96, 106, 116],
   [  7,  17,  27,  37,  47,  57,  67,  77,  87,  97, 107, 117],
   [  8,  18,  28,  38,  48,  58,  68,  78,  88,  98, 108, 118],
   [  9,  19,  29,  39,  49,  59,  69,  79,  89,  99, 109, 119],
   [ 10,  20,  30,  40,  50,  60,  70,  80,  90, 100, 110, 120]])

b已经是Fortran命令

c=b.reshape(10,3,4, order='F')
print(c[:,:,0])
[[ 1 11 21]
 [ 2 12 22]
 [ 3 13 23]
 [ 4 14 24]
 [ 5 15 25]
 [ 6 16 26]
 [ 7 17 27]
 [ 8 18 28]
 [ 9 19 29]
 [10 20 30]]

然后我将矩阵c保存在二进制文件中:

c.T.tofile('test_c.bin')

因此,使用这个Fortran代码,我能够以正确的顺序读取二进制数据,我在Python中创建了c矩阵:

PROGRAM read_saved_python
IMPLICIT NONE

INTEGER(KIND=8),ALLOCATABLE :: matrix(:,:,:)
INTEGER :: Nx, Ny, Nz

Nx = 10
Ny = 3
Nz = 4


ALLOCATE(matrix(Nx, Ny, Nz))


OPEN(33, FILE="/home/victor/test_c.bin",&
     FORM="UNFORMATTED", STATUS="UNKNOWN", ACTION="READ", ACCESS='STREAM')

READ(33) matrix


write(*,*) matrix(:,1,1)


CLOSE(33)
DEALLOCATE(matrix)

END PROGRAM read_saved_python

请注意,在Fortran中,索引从1开始,print按列顺序显示(在这种情况下:打印第一列,第二列,然后打印第三列)。如果你在Fortran中阅读时没有在c.T.tofile('test_c.bin')转置矩阵,你会注意到矩阵不是你想要的,即使你像你一样使用函数np.asfortranarray(我甚至尝试np.asfortranarray(c).T.tofile('/home/victor/teste_d.bin')(只是为了确保),但矩阵在{2}中以二进制文件的顺序写入。

答案 1 :(得分:1)

您需要数组的元数据才能在FORTRAN中读取它。这个网站(https://scipy.github.io/old-wiki/pages/Cookbook/InputOutput.html)有一些关于使用libnpy编写的信息和一个示例代码fex.f95来读取二进制文件。