如何读取已知header和文件格式的二进制文件进行数据分析?
How to read a binary file with a known header and file format for data analysis?
我目前正在做一些基本的 analysis/trying 来制作工具来自动化我工作中一些更定量的部分。其中一项任务是分析来自本地仪器的数据,并使用该数据得出定量结论。最终目标是计算给定区域的数据覆盖百分比(区域 'x' 中的值超过值 'y' 的百分比是多少?)。但是,也有问题。
首先,我们正在查看的数据是二进制的。虽然数据的程序员指南记录了一些数据结构,但它们很少涉及如何实际利用数据在其专有程序之外进行分析。
其次,我是Python的新手。当我在 python 年前尝试编程任务时,我并没有做出任何有用的东西;我更擅长 shell 脚本编写,可以使用 html/javascript/php,并使用 Fortran 管理程序;我正在努力学习 Python 以实现多样化。
我对相关数据的了解:二进制文件包含 640 个字符长 header,由三部分组成。每个部分都是以下内容的混合体;无符号和有符号的 8、16 和 32 位整数;以及 16 位和 32 位二进制角度。在 header 之后,文件将数据的笛卡尔网格显示为 'image' 中的 'pixels'。 'image' 中的每个 'pixel' 都是一个 one-byte 无符号字符,其值介于 0 和 255 之间。'image' 是 'x by y' 的二维网格,其中next 'image' 出现在给定的字节数之后(在此数据集中,图像为 720 x 720 'pixels',因此 'images' 在 720^2 字节后分开)。
现在,我的目标只是将文件读入 python 程序并将各种“图像”分开以供检查。初始化的data/format如下:
testFile = 'C:/path/to/file/binaryFile'
headerFormat = '640c'
nBytesData = 720 * 720
# Below is commented out
inputFile = open(testfile, 'rb')
我已经能够将文件作为二进制文件读入,但我不知道如何检查它。第一直觉是尝试将其放入一个 numpy 数组中,但其他研究建议使用 struct
模块和 struct.unpack
来分解数据。根据我的阅读,以下块应该在初始 header 之后正确解压缩每个 'image',即使它不是最有效的方法:
header_size = struct.calcsize(headerFormat)
testUnpacked = []
with open(testFile, 'rb') as testData:
headerOut = testData.read(header_size)
print("header is: ", headerOut)
while True:
testContent = testData.read()
if not testContent: break
testArray = struct.unpack(testContent, nBytesData)
testUnpacked.append(testArray)
问题是我不知道如何将代码设置为unpack/skip header 到二进制文件。我不认为 headerFormat = '640c'
行代码,加上接下来的几个命令来尝试格式化它的输出,是正确的。我能够输出一行程序 运行 in PyCharm,解释为“header”,下面是从第一个 [=62= 开始的输出示例]:
b'\x1b\x00\x08\x00\x80\xd4\x0f\x00\x00\x00\x00\x00\x1a\x00\x06\x00@\x01\x00\x00\x00\x00\x00\x00\x03\x00\x02\x00\x00\x00\x00\x00}\t\x0
之后,我得到一个错误,指出有一个嵌入的空字符阻止数据保存到指定的数组。
我参考的其他问题以尝试弄清楚如何读取数据:
Reading a binary file with python
Reading a binary file into a struct
主要问题如下:
- 如何让程序读取二进制文件header,然后根据720^2数组开始读取文件?
- 如何告诉程序以我能理解的格式保存 header?
- 如何找出导致 struct.error 消息的原因?
根据此描述,很难说如何阅读 header,因为这取决于其特定结构。应该可以阅读文件的其余部分。
首先将文件读取为字节数组:
with open(testFile, 'rb') as testData:
data = testData.read()
len(data)
会给出字节数。假设 header 包含少于 720^2 个字节,其余字节被细分为每个 720^2 个字节的图像,len(data)
除以 720^2 的提示将给出 header:
的长度
len_header = len(data) % 720**2
然后您可以忽略 header 并将剩余的字节转换为整数:
pixels = [b for b in data[len_header:]]
接下来,您可以使用 numpy 将此列表重新排列为具有 720^2 列的二维数组,以便每行由单个图像的像素组成:
import numpy as np
images = np.array(pixels).reshape(-1, 720**2)
每个图像现在都可以作为 images[i]
访问,其中 i
是行的索引。这是一个一维数组,所以要把它做成一个二维结构表示图像再reshape:
images[i].reshape(720, 720)
最后,你可以使用matplotlib显示图像并检查它看起来是否正确:
import matplotlib.pyplot as plt
plt.imshow(images[i].reshape(720, 720), cmap="gray_r")
plt.show()
我目前正在做一些基本的 analysis/trying 来制作工具来自动化我工作中一些更定量的部分。其中一项任务是分析来自本地仪器的数据,并使用该数据得出定量结论。最终目标是计算给定区域的数据覆盖百分比(区域 'x' 中的值超过值 'y' 的百分比是多少?)。但是,也有问题。
首先,我们正在查看的数据是二进制的。虽然数据的程序员指南记录了一些数据结构,但它们很少涉及如何实际利用数据在其专有程序之外进行分析。
其次,我是Python的新手。当我在 python 年前尝试编程任务时,我并没有做出任何有用的东西;我更擅长 shell 脚本编写,可以使用 html/javascript/php,并使用 Fortran 管理程序;我正在努力学习 Python 以实现多样化。
我对相关数据的了解:二进制文件包含 640 个字符长 header,由三部分组成。每个部分都是以下内容的混合体;无符号和有符号的 8、16 和 32 位整数;以及 16 位和 32 位二进制角度。在 header 之后,文件将数据的笛卡尔网格显示为 'image' 中的 'pixels'。 'image' 中的每个 'pixel' 都是一个 one-byte 无符号字符,其值介于 0 和 255 之间。'image' 是 'x by y' 的二维网格,其中next 'image' 出现在给定的字节数之后(在此数据集中,图像为 720 x 720 'pixels',因此 'images' 在 720^2 字节后分开)。
现在,我的目标只是将文件读入 python 程序并将各种“图像”分开以供检查。初始化的data/format如下:
testFile = 'C:/path/to/file/binaryFile'
headerFormat = '640c'
nBytesData = 720 * 720
# Below is commented out
inputFile = open(testfile, 'rb')
我已经能够将文件作为二进制文件读入,但我不知道如何检查它。第一直觉是尝试将其放入一个 numpy 数组中,但其他研究建议使用 struct
模块和 struct.unpack
来分解数据。根据我的阅读,以下块应该在初始 header 之后正确解压缩每个 'image',即使它不是最有效的方法:
header_size = struct.calcsize(headerFormat)
testUnpacked = []
with open(testFile, 'rb') as testData:
headerOut = testData.read(header_size)
print("header is: ", headerOut)
while True:
testContent = testData.read()
if not testContent: break
testArray = struct.unpack(testContent, nBytesData)
testUnpacked.append(testArray)
问题是我不知道如何将代码设置为unpack/skip header 到二进制文件。我不认为 headerFormat = '640c'
行代码,加上接下来的几个命令来尝试格式化它的输出,是正确的。我能够输出一行程序 运行 in PyCharm,解释为“header”,下面是从第一个 [=62= 开始的输出示例]:
b'\x1b\x00\x08\x00\x80\xd4\x0f\x00\x00\x00\x00\x00\x1a\x00\x06\x00@\x01\x00\x00\x00\x00\x00\x00\x03\x00\x02\x00\x00\x00\x00\x00}\t\x0
之后,我得到一个错误,指出有一个嵌入的空字符阻止数据保存到指定的数组。
我参考的其他问题以尝试弄清楚如何读取数据:
Reading a binary file with python
Reading a binary file into a struct
主要问题如下:
- 如何让程序读取二进制文件header,然后根据720^2数组开始读取文件?
- 如何告诉程序以我能理解的格式保存 header?
- 如何找出导致 struct.error 消息的原因?
根据此描述,很难说如何阅读 header,因为这取决于其特定结构。应该可以阅读文件的其余部分。
首先将文件读取为字节数组:
with open(testFile, 'rb') as testData:
data = testData.read()
len(data)
会给出字节数。假设 header 包含少于 720^2 个字节,其余字节被细分为每个 720^2 个字节的图像,len(data)
除以 720^2 的提示将给出 header:
len_header = len(data) % 720**2
然后您可以忽略 header 并将剩余的字节转换为整数:
pixels = [b for b in data[len_header:]]
接下来,您可以使用 numpy 将此列表重新排列为具有 720^2 列的二维数组,以便每行由单个图像的像素组成:
import numpy as np
images = np.array(pixels).reshape(-1, 720**2)
每个图像现在都可以作为 images[i]
访问,其中 i
是行的索引。这是一个一维数组,所以要把它做成一个二维结构表示图像再reshape:
images[i].reshape(720, 720)
最后,你可以使用matplotlib显示图像并检查它看起来是否正确:
import matplotlib.pyplot as plt
plt.imshow(images[i].reshape(720, 720), cmap="gray_r")
plt.show()