在Python中读取Fortran二进制文件

2023-12-03

我在用 Python 读取未格式化的 F77 二进制文件时遇到问题。 我已经尝试过SciPy.io.FortraFile方法和NumPy.fromfile方法,均无济于事。我还阅读了 IDL 中的文件,该文件有效,因此我对数据应该是什么样子有了一个基准。我希望有人能指出我的一个愚蠢的错误——没有什么比有一个白痴时刻然后洗手更好的了......

数据 bcube1 的尺寸为 101x101x101x3,且为 r*8 类型。总共有 3090903 个条目。它们是使用以下语句编写的(不是我的代码,从源代码复制)。

open (unit=21, file=bendnm, status='new'
.     ,form='unformatted')
write (21) bcube1
close (unit=21)

我可以使用以下代码在 IDL 中成功读取它(也不是我的代码,是从同事那里复制的):

bcube=dblarr(101,101,101,3)
openr,lun,'bcube.0000000',/get_lun,/f77_unformatted,/swap_if_little_endian
readu,lun,bcube
free_lun,lun

返回的数据 (bcube) 是双精度的,尺寸为 101x101x101x3,因此文件的标头信息知道其尺寸(而不是展平)。

现在我尝试使用 Python 获得相同的效果,但没有成功。我尝试过以下方法。

In [30]: f = scipy.io.FortranFile('bcube.0000000', header_dtype='uint32')
In [31]: b = f.read_record(dtype='float64')

返回错误Size obtained (3092150529) is not a multiple of the dtypes given (8)。更改 dtype 会更改获得的大小,但它仍然不能被 8 整除。

或者,使用fromfile结果没有错误,但返回数组中的另一个值(也许是页脚?),并且各个数组值都非常错误(应该全部具有统一的顺序)。

In [38]: f = np.fromfile('bcube.0000000')
In [39]: f.shape
Out[39]: (3090904,)
In [42]: f
Out[42]: array([ -3.09179121e-030,   4.97284231e-020,  -1.06514594e+299, ...,
         8.97359707e-029,   6.79921640e-316,  -1.79102266e-037])

我尝试使用 byteswap 来查看这是否使浮点值更合理,但事实并非如此。

在我看来,np.fromfile方法非常接近工作,但它读取标题信息的方式一定有问题。谁能建议我如何弄清楚什么should位于允许 IDL 了解数组维度和数据类型的头文件中吗?有没有办法将标头信息传递给fromfile这样它就知道如何处理领先的条目?


我玩了一下,我想我有一个想法。

Fortran 如何存储未格式化的数据尚未标准化,因此您必须稍微尝试一下,但您需要三个信息:

  1. 数据的格式。你建议是 64 位实数,或者 python 中的“f8”。
  2. 标头的类型。这是一个无符号整数,但您需要以字节为单位的长度。如果不确定,请尝试 4。

    标头通常存储记录的长度(以字节为单位),并在末尾重复。

    话又说回来,它不是标准化的,所以没有保证。

  3. 字节顺序,小或大。

    从技术上讲,对于标头和值,但我认为它们是相同的。

    Python 默认为小端,所以如果这是您的数据的正确设置,我想您已经解决了它。

当您使用以下命令打开文件时scipy.io.FortranFile,您需要给出的数据类型header。因此,如果数据存储为 big_endian,并且您有一个 4 字节无符号整数标头,则需要这样:

from scipy.io import FortranFile
ff = FortranFile('data.dat', 'r', '>u4')

当您读取数据时,您需要值的数据类型。再次,假设 big_endian,你想要输入>f8:

vals = ff.read_reals('>f8')

Look here有关数据类型语法的描述。

如果您可以控制写入数据的程序,我强烈建议您将它们写入数据流,这样Python可以更轻松地读取数据流。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

在Python中读取Fortran二进制文件 的相关文章

  • 使用带有不匹配索引的 pandas .loc 时内存爆炸+分配导致重复轴错误

    这是一个观察将 pandas 单元格与条件连接起来的最 Pythonic 方法 https stackoverflow com questions 69313521 most pythonic way to concatenate pand
  • 如何优化打印两个整数中较大者和较小者之间的差异?

    可能是最简单的问题 输入由一系列 2 32 的无符号整数对组成 因此要求使用 64 位整数 对于每一对 任务是打印出较大整数和较小整数之间的差异 根据 最快的解决方案运行时间低于 0 01 秒 然而 我解决这个问题的所有尝试通常都在 0 0
  • scipy 稀疏矩阵的元素级 exp()

    我有一个很大稀疏csc matrix x 我想对其进行元素 exp 基本上我想要的是得到与我得到的结果相同的结果numpy exp x toarray 但我不能这样做 我的记忆不允许我将稀疏矩阵转换为数组 还有出路吗 提前致谢 如果你没有记
  • 调用 close() 后大文件没有立即刷新到磁盘?

    我正在使用 python 脚本创建大文件 超过1GB 实际上有 8 个 在创建它们之后 我必须创建将使用这些文件的进程 该脚本如下所示 This is more complex function but it basically does
  • 将任何文件读取为二进制字符串

    正如标题所示 有什么方法可以读取 Java 或任何其他语言 中给定文件 txt docx exe 等 的二进制表示形式 在java中 我知道如何按原样读取文件的内容 即 String line BufferedReader br new B
  • 错误:(1) 处的分配中的等级 0 和 1 不兼容

    我正在不规则网格上使用有限差分方法 这是代码的重要部分 IMPLICIT DOUBLE PRECISION A Z REAL 16 IPSI ICORR POT 20000 VA 20000 delta1 20000 delta2 2000
  • OpenCV - 我需要将彩色图像插入黑白图像并且

    我用以下代码将黑白图像插入彩色图像 没问题 face grey cv cvtColor face cv COLOR RGB2GRAY for row in range 0 face grey shape 0 for column in ra
  • 接口不匹配 - 高阶函数

    我正在尝试在 Fortran 中 重现 高阶函数 module rk4 contains pure function f t x result fx real dimension 1 intent in x real intent in t
  • 在python中安装scipy模块时出错

    我正在尝试使用 pip 在 python 中安装 scipy 模块 它显示以下错误 Command c users sony appdata local programs python python35 32 python exe u c
  • 科学 Fortran 编译错误

    我正在研究科学建模程序 但还没有让我的程序编译 我没有碰过我的教授坚持认为以前有效的代码 只碰过 makefile 经过多次尝试 我得到的最远的是这个错误 Error on line 1112 Declaration error for x
  • 将 x 轴绘制为日期

    我正在尝试对数据进行一些分析 我得到了 csv 文件并将其转换为 pandas 数据框 数据看起来像这样 它有几列 但我试图将 x 轴绘制为日期列 pandas 数据框看起来像这样 print df head 10 cus id date
  • 从椭圆生成数组

    我有一个方程 它以一般形式 x 2 a 2 y 2 b 2 1 创建一个椭圆 我希望生成一个数组 其中椭圆内部的所有点都设置为 1 椭圆外部的所有点都设置为 1是零 然后这个数组将与另一个数组进行卷积 到目前为止 我已尝试创建一个大小为空的
  • Fortran + Openmp 比顺序更慢

    我有这个 Fortran 语言的顺序代码 我的问题是 当我放置 Openmp 指令时 并行代码比顺序代码更慢 并且我没有看到错误 REAL DIMENSION ALLOCATABLE current next ALLOCATE curren
  • 如何从第二个索引开始for循环

    我有这个for循环 我想i in range nI 从第二个数字开始I列表 你能指导我吗 I 0 1 2 3 4 5 6 nI len I for i in range nI sum 0 for v in range nV for j in
  • 在 python numpy 中构建一个 nxn 矩阵,对于任何 n

    是否可以使用 python 的 numpy 版本 3 3 编写构建 nxn 矩阵的代码 而不指定 n 我需要将条目索引为 A i j 或类似的东西 但我什至不知道如何定义 A i j 以便它们实际上是对象 我认为这样的事情可能会起作用 n
  • RuntimeError:尝试在 tflearn 中使用关闭的会话

    我想用 tflearn 训练我的模型 但出现上面显示的错误 这是我的训练循环 顺便说一句 我将训练输入拆分为单独的 numpy 文件 for i in range EPOCHS for file in filess file np load
  • 使用 Java 在 Windows 中删除文件失败

    我一直在尝试使用Java IO删除Windows操作系统中的文件file delete API 然而它失败并返回 false 相同的代码在 Ubuntu 中就像魅力一样 我已验证该文件的权限允许程序删除它 此外 文件的所有输入和输出流都已作
  • 在android中获取可移动SD卡路径

    我如何在android中获取extSdcard路径 有 2 个存储 第一个是所有手机都有的外部存储 但第二个存储称为可移动存储 微型 SD 卡 我想在android中获取micro SD卡的路径 这怎么可能 从 KitKat 开始 您可以访
  • python中matlab find函数的替换

    我正在尝试寻找合适的python函数来替代matlabfind在我的脚本和一些谷歌搜索中我看到np where 大多数时候都能解决目的 但在双重条件的情况下 我有不同的输出 有人可以告诉我这种方法有什么问题以及如何继续吗 示例代码和差异如下
  • Numpy 相当于 if/else 不带循环

    有没有任何Pythonic方法可以删除下面代码中的for循环和if else 此代码迭代 NumPy 数组并检查条件并根据条件更改值 gt gt gt import numpy as np gt gt gt x np random rand

随机推荐