Single tensors · .npy

NumPy .npy array file

A single N-d array: a 6-byte magic, 2 version bytes, a little-endian header length, and an ASCII/latin1/UTF-8 Python-dict-literal header {'descr','fortran_order','shape'} padded so the data starts at a multiple of 64, then the raw array bytes in C or Fortran order. Byte order is declared per array in descr, so big-endian is possible. Object arrays are stored as a pickle (unsafe). It is the simplest cross-language interchange format for one tensor, with readers for C/C++ (cnpy, xtensor), Rust (ndarray-npy, npyz), Julia, JS and Go.

.npy

What it is
one tensor
Byte order
per array declared
Dimension order
per array flag
Compression
none
Metadata
none
Loading
Loading it into a library can execute code, depending on the loader and the file.

How to read it

magic(6) | major(1) | minor(1) | HEADER_LEN (u16 v1 / u32 v2,v3 LE) | header text | data

magic
bytes[6]
major
u8
minor
u8
header_len
u16le
header_len
u32le
header
latin1[header_len] | utf8[header_len]
data
bytes[prod(shape)*itemsize]. for 'O' arrays: a pickle stream instead
0      6  7  8        10/12                                      64*k
+------+--+--+--------+-----------------------------------------+-------------+
|\x93NUMPY|ma|mi| HLEN | {'descr': '<f4', 'fortran_order': ...}   \n| array bytes |
+------+--+--+--------+-----------------------------------------+-------------+

One tensor

name
none (derive from the file name)
dtype
header.descr (simple) -> canonical, ignoring the byte-order char
shape
header.shape (logical, outermost first, for both orders)
data_offset
len(magic)+2+len(header_len field)+header_len
nbytes
prod(shape) * itemsize
order
'F' if fortran_order else 'C'
byte_order
descr[0]: '<' little, '>' big, '|' n/a

Example

The specs test vector. numpy 2.5.4 wrote this file. The file has no array name inside it; the name is the stem, w_f32.

w_f32.npy1,152 bytes

NameDtypeShapeBytes
w_f32<f4float324 × 641,024

Header

{'descr': '<f4', 'fortran_order': False, 'shape': (4, 64), }

Number formats

The name in the file, and the canonical dtype it maps to.

In the fileCanonicalBits
boolbool8
int8int88
uint8uint88
int16int1616
uint16uint1616
int32int3232
uint32uint3232
int64int6464
uint64uint6464
float16float1616
float32float3232
float64float6464
longdoublenone128
complex64complex6464
complex128complex128128
datetime64none64
timedelta64none64
bytesnone—
strnone—
voidnone—
objectnone—
structurednone—

Sources

Nick Reynolds · @goldnode · nicks.net · rev 0.1