python - gzip.open().read() 的大小参数

标签 python gzip

在 Python 中使用 gzip 库时,我经常会遇到使用 .read() 函数的代码,其模式如下所示:

with gzip.open(filename) as bytestream:
    bytestream.read(16) 
    buf = bytestream.read(
        IMAGE_SIZE * IMAGE_SIZE * num_images * NUM_CHANNELS
    )
    data = np.frombuffer(buf, dtype=np.uint8).astype(np.float32)

虽然我熟悉上下文管理器模式,但我很难真正理解 with 上下文管理器中的第一行代码到底在做什么。

这是read() 函数的文档:

Read at most n characters from stream.

Read from underlying buffer until we have n characters or we hit EOF. If n is negative or omitted, read until EOF.

如果是这样,第一行 bytestream.read(16) 的功能角色将必须读取并因此跳过前 16 个字符,大概是因为它们充当元数据或标题。但是,当我有一些图像时,我怎么知道使用 16 作为 read 调用的参数,而不是 32、8 或 64?

我记得有很多次遇到与上面完全相同的代码,除了作者使用 bytestream.read(8) 而不是 bytestream.read(16) 或者只是可能,任何其他值。逐个字符地深入文件显示没有可识别的模式来确定标题字符的长度。

换句话说,如何确定要在 read 函数调用中使用的参数? 或者如何知道 gzip 中标题字符的长度-压缩文件?

我的猜测是它与字节有关,但在搜索文档和在线引用资料后我无法证实这一点。

可重现的细节

我的假设是,经过无数小时的故障排除后,前 16 个字符代表某种标题或元数据。所以该代码的第一行是跳过 16 个字符并将剩余的字符存储在名为 buf 的变量中。但是,通过深入研究数据,我发现无法确定为什么或如何选择值 16。我已经逐个字符地读取字节,也尝试读取 + 将它们转换为 np.float,但是没有明显的模式表明元数据在第 16 个字符和实际数据处结束17日开始。

以下代码从this website中读取数据并提取前 30 个字符。请注意,标题行“结束”(显然是第 16 行,在\x1c` 第二次出现之后)和数据开始的位置是难以辨认的:

import gzip
import numpy as np

train_data_filename = 'data_input/train-images-idx3-ubyte.gz'
IMAGE_SIZE = 28
NUM_CHANNELS = 1

def extract_data(filename, num_images):
    with gzip.open(filename) as bytestream:
        first30 = bytestream.read(30)
        return first30

first30= extract_data(train_data_filename, 10)
print(first30)
# returns: b'\x00\x00\x08\x03\x00\x00\xea`\x00\x00\x00\x1c\x00\x00\x00\x1c\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'

如果我们修改代码以将它们转换为 np.float32,这样所有字符现在都是数字(浮点),同样没有明显的模式来区分标题/元数据的位置结束和数据开始的地方。

如有任何引用或建议,我们将不胜感激!

最佳答案

从 gzip 的角度来看,它返回给您的一切都是数据。 没有该数据流前面没有元数据或特定于 gzip 的 header 内容,因此不需要任何类型的算法来计算 gzip 为该流添加了多少内容:它的字节数前置为零。


向下滚动到您链接的页面底部;有一个标题为 FILE FORMATS FOR THE MNIST DATABASE 的标题。

该格式规范准​​确地告诉您格式是什么,以及每个 header 使用了多少字节。具体来说,每个文件中的前四项描述如下:

0000     32 bit integer  0x00000803(2051) magic number 
0004     32 bit integer  60000            number of images 
0008     32 bit integer  28               number of rows 
0012     32 bit integer  28               number of columns 

因此,如果您想跳过所有这四个项目,您需要从顶部移除 16 个字节。

关于python - gzip.open().read() 的大小参数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54019755/

相关文章:

python - 如何高效地预处理和解析JSON数据?

python - 在按钮上单击打开 wxpython TextEntryDialog 并从用户那里获取多个输入

python - 子流程变量

python - 创建具有图像识别功能的独立项目

nginx - 静态文件显示为未压缩,即使 Web 服务器已配置为 gzip 压缩

bash - 如何在不解压缩的情况下从 gzip 文件中删除第一行?

javascript - 使用 Pako 在 Javascript 中提取 gzip 数据 - 编码问题

python - 如何在模型过滤器中过滤日期时间的工作日?

hadoop - 解压时如何读取压缩文件?

node.js - 我如何在 express 中压缩 POST 请求数据?