【问题标题】:Why do we need endianness here?为什么我们在这里需要字节序?
【发布时间】:2016-02-15 00:14:05
【问题描述】:

我正在阅读source-code,它会下载 zip 文件并将数据读入 numpy 数组。该代码假设适用于 macos 和 linux,这是我看到的 sn-p:

def _read32(bytestream):
    dt = numpy.dtype(numpy.uint32).newbyteorder('>')
    return numpy.frombuffer(bytestream.read(4), dtype=dt)

此函数用于以下上下文:

with gzip.open(filename) as bytestream:
    magic = _read32(bytestream)

不难看出这里发生了什么,但我对newbyteorder('>') 的目的感到困惑。我读了documentation,知道字节序是什么意思,但不明白为什么开发人员添加了newbyteorder(我认为它并不是真正需要的)。

【问题讨论】:

    标签: python numpy endianness


    【解决方案1】:

    这只是一种确保以正确顺序从结果数组中解释字节的方法,而不管系统的本机字节顺序如何。

    默认情况下,内置的 NumPy 整数 dtypes 将使用系统原生的字节顺序。例如,我的系统是 little-endian,因此仅使用 dtype numpy.dtype(numpy.uint32) 将意味着无法正确解释从缓冲区中以 big-endian 顺序读入数组的值。

    如果np.frombuffer 旨在接收已知处于特定字节顺序中的字节,最佳实践是使用newbyteorder 修改dtype。 documents for np.frombuffer中提到了这一点:

    注意事项

    如果缓冲区中的数据不是机器字节顺序的,则应将其指定为数据类型的一部分,例如:

    >>> dt = np.dtype(int)
    >>> dt = dt.newbyteorder('>')
    >>> np.frombuffer(buf, dtype=dt)
    

    结果数组的数据不会被字节交换,而是会被 正确解释。

    【讨论】:

      【解决方案2】:

      这是因为下载的数据是大端格式,如源页面所述:http://yann.lecun.com/exdb/mnist/

      文件中的所有整数都先存储在MSB中(高位 大多数非英特尔处理器使用的字节序)格式。英特尔用户 处理器和其他低端机器必须翻转 标题。

      【讨论】:

      • 如果你看一下第 45 行的代码,你会看到`data = numpy.frombuffer(buf, dtype=numpy.uint8)`。这会让事情变得有点混乱。为什么在这行代码中没有指定字节顺序?
      • 因为数据类型 uint8 只有 1 个字节长。字节序仅对多字节数据类型有意义。
      猜你喜欢
      • 2010-11-10
      • 1970-01-01
      • 1970-01-01
      • 2021-11-02
      • 2012-06-03
      • 1970-01-01
      • 2021-08-27
      • 2011-06-28
      • 2019-06-09
      相关资源
      最近更新 更多