你写的代码几乎正确,但是`.tofile`方法总是按C顺序写入向量。我不知道为什么`np.asfortranarray()`在写入二进制文件时可以避免这个问题,但是我进行了测试,不幸的是我们需要在写入之前转置矩阵以便在Fortran中正确读取而不需要任何其他考虑(这意味着在Fortran中你可以给出实际的矩阵维度而不需要任何转置)。下面的代码是为了说明我所说的,使用一个三维矩阵(我通常需要使用):
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
按列顺序显示(在这种情况下:先打印第一列,然后是第二列,最后是第三列)。如果您不在此处转置矩阵
c.T.tofile('test_c.bin')
,当在Fortran中读取时,您会注意到矩阵不是您想要的,即使您使用了函数
np.asfortranarray
(就像您所做的那样),但是矩阵仍以
c
顺序写入二进制文件中。
tofile
是数组的一个方法,而不是文件。无论如何,在 Fortran 中你肯定可以使用access=stream
和form=unformatted
打开文件并读取原始二进制数据。 - agentp