2015-11-13 16 views
10

Sto leggendo un source-code che scarica il file zip e legge i dati in una matrice numpy. Il codice si supponga di lavorare su MacOS e Linux ed ecco il frammento di che vedo:Perché abbiamo bisogno di endianness qui?

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

Questa funzione viene utilizzata nel seguente contesto:

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

Non è difficile vedere cosa succede qui , ma sono perplesso dallo scopo di newbyteorder('>'). Ho letto il documentation e so cosa significa endianness, ma non riesco a capire perché esattamente lo sviluppatore abbia aggiunto newbyteorder (a mio parere non è davvero necessario).

risposta

7

Questo perché i dati scaricati sono in formato big endian come descritto nella pagina di origine: http://yann.lecun.com/exdb/mnist/

Tutti gli interi nei file sono memorizzati nella MSB prima (alta endian) formato utilizzato dalla maggior parte dei non-Intel processori. Gli utenti dei processori Intel e di altre macchine di fascia bassa devono capovolgere i byte dell'intestazione .

+0

Se date un'occhiata al codice alla riga 45 vedete 'data = numpy.frombuffer (buf, dtype = numpy.uint8)'. Questo fa pasticciare un po 'le cose. Perché in questa riga di codice non viene specificata l'endianità? – emanuele

+1

Poiché il tipo di dati 'uint8' è lungo solo 1 byte. Endianness è significativo solo per tipi di dati multi-byte. – HeyYO

+0

grazie :) hai ragione – emanuele

3

È solo un modo per garantire che i byte vengano interpretati dall'array risultante nell'ordine corretto, indipendentemente dal byteorder nativo di un sistema.

Per impostazione predefinita, i tipi di codice intero NumPy incorporati utilizzano il byteorder nativo del sistema. Ad esempio, il mio sistema è little-endian, quindi usare semplicemente il dtype numpy.dtype(numpy.uint32) significa che i valori letti in un array da un buffer con i byte nell'ordine big-endian non verranno interpretati correttamente.

Se np.frombuffer intende ricevere i byte noti in un determinato byteorder, è consigliabile modificare il dtype utilizzando newbyteorder. Questo è menzionato nella documents for np.frombuffer:

Note

Se il buffer contiene dati che non è in macchina di byte-ordine, questo dovrebbe essere specificato come parte del tipo di dati, ad esempio:

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

I dati dell'array risultante non verranno scambiati bytes, ma saranno interpretati correttamente .

Problemi correlati