2015-11-13 60 views
10

我正在阅读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,并知道什么endianness的意思,但不明白为什么开发人员加入newbyteorder(在我看来它不是真的需要)。

回答

7

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

所有这些文件中的整数存储在MSB第一(高 端)格式使用的大多数非Intel处理器。英特尔 处理器和其他低端机器的用户必须翻转 标头的字节。

+0

如果你看看第45行的代码,你会看到'data = numpy.frombuffer(buf,dtype = numpy.uint8)'。这会让事情变得有点混乱。为什么在这行代码中没有指定字节序? – emanuele

+1

因为数据类型'uint8'只有1个字节长。字节序仅对多字节数据类型有意义。 – HeyYO

+0

thanx :)你说得对 – emanuele

3

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

默认情况下,内置的NumPy integer dtypes将使用系统本机的字节序。例如,我的系统是小端的,所以简单地使用dtype numpy.dtype(numpy.uint32)将意味着从缓冲区读入数组的数据值将不会被正确解释。

如果np.frombuffer是为了接收已知为特定字节顺序的字节,最好的做法是使用newbyteorder来修改dtype。这在documents for np.frombuffer提到:

如果缓冲器有数据,是不是在机器字节顺序,这应该被指定为数据型的一部分,例如:

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

结果数组的数据不会被字节切换,但会被正确解释为 。

相关问题