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
| Name | Dtype | Shape | Bytes |
|---|---|---|---|
| w_f32 | <f4float32 | 4 × 64 | 1,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 file | Canonical | Bits |
|---|---|---|
| bool | bool | 8 |
| int8 | int8 | 8 |
| uint8 | uint8 | 8 |
| int16 | int16 | 16 |
| uint16 | uint16 | 16 |
| int32 | int32 | 32 |
| uint32 | uint32 | 32 |
| int64 | int64 | 64 |
| uint64 | uint64 | 64 |
| float16 | float16 | 16 |
| float32 | float32 | 32 |
| float64 | float64 | 64 |
| longdouble | none | 128 |
| complex64 | complex64 | 64 |
| complex128 | complex128 | 128 |
| datetime64 | none | 64 |
| timedelta64 | none | 64 |
| bytes | none | — |
| str | none | — |
| void | none | — |
| object | none | — |
| structured | none | — |