【问题标题】:Is the bytes offset in files produced by np.save always 128?np.save 生成​​的文件中的字节偏移量是否始终为 128?
【发布时间】:2018-07-12 21:29:43
【问题描述】:

我一直在玩 numpy memmaps,我注意到如果我生成一些数据并将其转储到磁盘上:

from os.path import join
import numpy as np
import tempfile

print('Generate dummy data')
N = 4
D = 3
x, y = np.meshgrid(np.arange(0, N), np.arange(0, N))
data = np.ascontiguousarray((np.dstack([x] * D) % 256).astype(np.uint8))

print('Make temp directory')
dpath = tempfile.mkdtemp()
mem_fpath = join(dpath, 'foo.npy')

print('Dump memmap')
np.save(mem_fpath, data)

那么np.memmapnp.load产生的数据就不同了。

file1 = np.memmap(mem_fpath, dtype=data.dtype.name, shape=data.shape,
                  mode='r')
file2 = np.load(mem_fpath)
print('file1 =\n{!r}'.format(file1[0]))
print('file2 =\n{!r}'.format(file2[0]))

导致

file1 =
memmap([[147,  78,  85],
        [ 77,  80,  89],
        [  1,   0, 118],
        [  0, 123,  39]], dtype=uint8)
file2 =
array([[0, 0, 0],
       [1, 1, 1],
       [2, 2, 2],
       [3, 3, 3]], dtype=uint8)

这让我很困惑,但最终我发现我需要将 np.memmap 中的 offset 参数设置为 128 才能使其工作:

for i in range(0, 1000):
    file1 = np.memmap(mem_fpath, dtype=data.dtype.name, shape=data.shape,
                      offset=i, mode='r')
    if np.all(file1 == data):
        print('i = {!r}'.format(i))
        break

print('file1 =\n{!r}'.format(file1[0]))

执行结果

i = 128
file1 =
memmap([[0, 0, 0],
        [1, 1, 1],
        [2, 2, 2],
        [3, 3, 3]], dtype=uint8)

我的问题是这个 128 号码是从哪里来的。我检查了 np.save 文档,但没有看到对它的引用。我也尝试修改数据的 dtype 和 shape,但我总是发现偏移量是 128。我可以假设使用np.save 保存的任何单个数组都将始终具有这个 128 偏移量吗?如果不是,我如何确定偏移量应该是多少。

我问的原因是因为我发现使用 np.memmap 比 np.load 快得多,因为我从磁盘上的大文件中裁剪小区域的特定用例。

感谢您的帮助!

【问题讨论】:

    标签: python numpy


    【解决方案1】:

    您看到的 128 字节偏移应该被认为是实现的侥幸。 NPY 文件头的长度是 required 是 16 的倍数,而实现 currently 对齐到 64 字节,因为 16 不足以在所有平台上进行内存映射。

    128 字节将是 非常常见的 标头大小,因为标头中的样板文件大约需要 64 个字节,并且大多数数组没有足够复杂的格式来要求超过 128 字节的标头描述他们。但是,结构化数组很容易产生超过 128 字节的标头,并且由旧 NumPy 版本或格式的不同实现生成的 NPY 文件可能具有不同的对齐方式。

    【讨论】:

    • 保存文件时有什么方法可以确定标题的大小? (除了我在主要问题中使用的蛮力方法?)
    • @Erotemic:您可以解析足够的标题以确定数组数据的开始位置。格式为documented
    猜你喜欢
    • 1970-01-01
    • 2014-04-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-09-25
    • 1970-01-01
    • 1970-01-01
    • 2015-11-27
    相关资源
    最近更新 更多