为什么我们在这里需要字节顺序?

Why do we need endianness here?

我正在阅读 source-code,它会下载 zip 文件并将数据读入 numpy 数组。该代码假设在 macos 和 linux 上工作,这是我看到的代码片段:

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(在我看来它并不是真正需要的)。

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

All the integers in the files are stored in the MSB first (high endian) format used by most non-Intel processors. Users of Intel processors and other low-endian machines must flip the bytes of the header.

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

默认情况下,内置的 NumPy 整数 dtypes 将使用系统本机的字节顺序。例如,我的系统是 little-endian,所以简单地使用 dtype numpy.dtype(numpy.uint32) 将意味着从缓冲区读取到数组中的值将无法正确解释字节顺序为 big-endian 的值。

如果 np.frombuffer 是为了接收已知以特定字节顺序排列的字节,最佳做法是使用 newbyteorder 修改 dtype。 documents for np.frombuffer:

中提到了这一点

Notes

If the buffer has data that is not in machine byte-order, this should be specified as part of the data-type, e.g.:

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

The data of the resulting array will not be byteswapped, but will be interpreted correctly.