Python 如何将未格式化的fortran文件(modflow输出)转换为numpy数组

Python 如何将未格式化的fortran文件(modflow输出)转换为numpy数组,python,arrays,numpy,fortran,flopy,Python,Arrays,Numpy,Fortran,Flopy,我有一个扩展名为hds的modflow输出文件。谷歌驱动器链接。这是一个未格式化的fortran文件。我需要将其转换为numpy数组,我已尝试: floattype = 'f4' a = np.fromfile("lake_example.hds", np.dtype([('kstp','i4'),('kper','i4'),('pertim',floattype),('totim',floattype),('text','a16'),('ncol','i4'),('nrow','i4'),('

我有一个扩展名为hds的modflow输出文件。谷歌驱动器链接。这是一个未格式化的fortran文件。我需要将其转换为numpy数组,我已尝试:

floattype = 'f4'
a = np.fromfile("lake_example.hds", np.dtype([('kstp','i4'),('kper','i4'),('pertim',floattype),('totim',floattype),('text','a16'),('ncol','i4'),('nrow','i4'),('ilay','i4')]))
print a
print a.shape
代码的github链接:

我是一个尝试从一个教程。因为我在linux上,所以不能使用flopy的方法从文件中获取输出数组。所以我尝试使用np.fromfile,但在获取输出时遇到了问题

现在我的输出是这样的:

[ (44, 1, 1.401298464324817e-45, 1.0, '\x00\x00\x80?            ', 1145128264, 11, 11)
 (1, 44, 6.782284567332115e-43, 100.0, '\x00\x00\xc8B\x00\x00\xc8B\x00\x00\xc8B\x00\x00\xc8B', 1120403456, 1120403456, 1120403456)
 (1120403456, 1120403456, 100.0, 100.0, '\x0c\xbf\xc7B\x18~\xc7B=@\xc7B\xce\x0e\xc7B', 1120336356, 1120341710, 1120354365)
 (1120370200, 1120386828, 100.0, 100.0, '\x18~\xc7B\x0e\xf9\xc6B\xf0s\xc6B\xaa\x00\xc6B', 1120258308, 1120272554, 1120302064)
 (1120336142, 1120370200, 100.0, 100.0, '=@\xc7B\xf0s\xc6B\xf8\x94\xc5B\x91\xb3\xc4B', 1120149448, 1120187281, 1120244984)
 (1120302064, 1120354365, 100.0, 100.0, '\xce\x0e\xc7B\xaa\x00\xc6B\x91\xb3\xc4B\xac\xff\xc2B', 1119940155, 1120075692, 1120187281)
 (1120272554, 1120341710, 100.0, 100.0, '\xe4\xf9\xc6B\x04\xc9\xc5B\xc8\x1f\xc4B;\xee\xc0B', 1119092736, 1119940155, 1120149448)
 (1120258308, 1120336356, 100.0, 100.0, '\xce\x0e\xc7B\xaa\x00\xc6B\x91\xb3\xc4B\xac\xff\xc2B', 1119940155, 1120075692, 1120187281)
 (1120272554, 1120341710, 100.0, 100.0, '=@\xc7B\xf0s\xc6B\xf8\x94\xc5B\x91\xb3\xc4B', 1120149448, 1120187281, 1120244984)
 (1120302064, 1120354365, 100.0, 100.0, '\x18~\xc7B\x0e\xf9\xc6B\xf0s\xc6B\xaa\x00\xc6B', 1120258308, 1120272554, 1120302064)
 (1120336142, 1120370200, 100.0, 100.0, '\x0c\xbf\xc7B\x18~\xc7B=@\xc7B\xce\x0e\xc7B', 1120336356, 1120341710, 1120354365)
我只包含了几行输出


有关标题信息,您可以参考其源代码:

您的代码与数据文件的结构不匹配:

00000000  2c 00 00 00 01 00 00 00  01 00 00 00 00 00 80 3f  |,..............?|
00000010  00 00 80 3f 20 20 20 20  20 20 20 20 20 20 20 20  |...?            |
00000020  48 45 41 44 0b 00 00 00  0b 00 00 00 01 00 00 00  |HEAD............|
00000030  2c 00 00 00 e4 01 00 00  00 00 c8 42 00 00 c8 42  |,..........B...B|
00000040  00 00 c8 42 00 00 c8 42  00 00 c8 42 00 00 c8 42  |...B...B...B...B|
00000050  00 00 c8 42 00 00 c8 42  00 00 c8 42 00 00 c8 42  |...B...B...B...B|
每个数据块都有自己的56字节报头,包括: 3个整数(i4)、2个浮点值(f4)、16个字符和5个整数(i4):

然后数据块如下(11x11浮点值):

我不确定这是否可以直接导入numpy数组

以下示例代码将在整个文件中循环,并提取每个块的头和数据:

#!/usr/bin/python

import struct
import numpy as np

infile = open("lake_example.hds","rb")

blockdata = []

while infile.read(1):
    infile.seek(-1,1)
    data = infile.read(56)
    n = struct.unpack('<3i4', data[0:12])
#    print n[0], n[1], n[2]
    n = struct.unpack('<2f4', data[12:20])
#    print n[0], n[1]
#    print data[20:36]
    n = struct.unpack('<5i4', data[36:56])
#    print n[0], n[1], n[2], n[3], n[4]
    ncol = n[0]
    nrow = n[1]
    a = np.fromfile(infile,dtype='f4',count=ncol*nrow).reshape((ncol,nrow))
    blockdata.append(a)
    data = infile.read(4)
    n = struct.unpack('<i4', data)
#    print n[0]

for block in blockdata:
    print block
#/usr/bin/python
导入结构
将numpy作为np导入
infle=开放(“lake_example.hds”、“rb”)
块数据=[]
填充时,读取(1):
填充搜索(-1,1)
数据=填充读取(56)

n=struct.unpack(“另请参见“flopy.utils.binaryfile模块”:

请参阅Flopy-3教程2(无侧限瞬态流模型),在绘图部分:

发件人:

首先定义“头对象”:

headobj = bf.HeadFile(modelname+'.hds')
头部提取如下:

head = headobj.get_data(totim=time)

在Debian上运行

我需要转换第二个数据块(11x11浮点值)你能告诉我如何在pythonI中提取不同的数据块吗?我更改了我的示例代码,现在它可以从文件中读取所有数据块。感谢klobrille,我已经找到了它。在编译Modflow时,你必须使用以下选项。在makefile中,使用F90=gfortran。在openspec.inc中,更改数据访问/“SEQUENTIAL”/toDATA访问/'STREAM'/将数据格式/'BINARY'/更改为数据格式/'UNFORMATTED'/
headobj = bf.HeadFile(modelname+'.hds')
head = headobj.get_data(totim=time)