|
1 | | -<h1 align=center>npy.js</h1> |
2 | | -<h6 align=center>Read .npy files directly in JS</h6> |
3 | | - |
4 | | -<p align=center> |
5 | | - <a href="https://www.npmjs.com/package/npyjs"><img src="https://img.shields.io/npm/v/npyjs.svg?style=for-the-badge" /></a> |
6 | | - <a href="https://github.com/aplbrain/npyjs"><img src="https://img.shields.io/github/issues/aplbrain/npyjs.svg?style=for-the-badge" /></a> |
7 | | - <a href="https://github.com/aplbrain/npyjs"><img src="https://img.shields.io/github/license/aplbrain/npyjs.svg?style=for-the-badge" /></a> |
8 | | - <img alt="GitHub Workflow Status" src="https://img.shields.io/github/actions/workflow/status/aplbrain/npyjs/test-node.yml?label=Tests&style=for-the-badge"> |
| 1 | +<h1 align="center">npyjs</h1> |
| 2 | +<h6 align="center">Read NumPy <code>.npy</code> files in JavaScript (Node, Browser, Deno)</h6> |
| 3 | + |
| 4 | +<p align="center"> |
| 5 | + <a href="https://www.npmjs.com/package/npyjs"><img src="https://img.shields.io/npm/v/npyjs.svg?style=for-the-badge" /></a> |
| 6 | + <a href="https://github.com/aplbrain/npyjs/issues"><img src="https://img.shields.io/github/issues/aplbrain/npyjs.svg?style=for-the-badge" /></a> |
| 7 | + <a href="https://github.com/aplbrain/npyjs/blob/main/LICENSE"><img src="https://img.shields.io/github/license/aplbrain/npyjs.svg?style=for-the-badge" /></a> |
| 8 | + <img alt="GitHub Workflow Status" src="https://img.shields.io/github/actions/workflow/status/aplbrain/npyjs/ci.yml?label=Tests&style=for-the-badge"> |
9 | 9 | </p> |
10 | 10 |
|
11 | | -Read .npy files from [numpy](https://numpy.org/doc/1.18/reference/generated/numpy.save.html) in Node/JS. |
| 11 | +Read `.npy` arrays saved with [NumPy](https://numpy.org/doc/stable/reference/generated/numpy.save.html) directly in modern JavaScript runtimes. |
12 | 12 |
|
13 | | -## Installation |
| 13 | +--- |
14 | 14 |
|
15 | | -Include npy.js in your project directly, or: |
| 15 | +## Installation |
16 | 16 |
|
17 | | -```shell |
| 17 | +```bash |
| 18 | +npm install npyjs |
| 19 | +# or |
18 | 20 | yarn add npyjs |
19 | | -# npm i npyjs |
20 | 21 | ``` |
21 | 22 |
|
| 23 | +Supports **Node ≥18**, modern browsers, and Deno/Bun. |
| 24 | + |
| 25 | +--- |
| 26 | + |
22 | 27 | ## Import |
23 | 28 |
|
24 | | -```javascript |
| 29 | +```ts |
| 30 | +// Modern named export (recommended) |
| 31 | +import { load } from "npyjs"; |
| 32 | + |
| 33 | +// Back-compatibility class (matches legacy docs/tests) |
25 | 34 | import npyjs from "npyjs"; |
26 | 35 | ``` |
27 | 36 |
|
| 37 | +--- |
| 38 | + |
28 | 39 | ## Usage |
29 | 40 |
|
30 | | -- Create a new npyjs object: |
| 41 | +### 1. Functional API (preferred) |
31 | 42 |
|
32 | | -```javascript |
33 | | -let n = new npyjs(); |
34 | | -// Or with options: |
35 | | -let n = new npyjs({ convertFloat16: false }); // Disable float16 to float32 conversion |
| 43 | +```ts |
| 44 | +import { load } from "npyjs"; |
| 45 | + |
| 46 | +const arr = await load("my-array.npy"); |
| 47 | +// arr has { data, shape, dtype, fortranOrder } |
| 48 | +console.log(arr.shape); // e.g., [100, 784] |
36 | 49 | ``` |
37 | 50 |
|
38 | | -- This object can now be used load .npy files. Arrays can be returned via a JavaScript callback, so usage looks like this: |
| 51 | +### 2. Legacy Class API (still supported) |
39 | 52 |
|
40 | | -```javascript |
41 | | -n.load("my-array.npy", (array, shape) => { |
42 | | - // `array` is a one-dimensional array of the raw data |
43 | | - // `shape` is a one-dimensional array that holds a numpy-style shape. |
44 | | - console.log(`You loaded an array with ${array.length} elements and ${shape.length} dimensions.`); |
45 | | -}); |
46 | | -``` |
| 53 | +```ts |
| 54 | +import npyjs from "npyjs"; |
47 | 55 |
|
48 | | -- You can also use this library promise-style using either .then or async await: |
| 56 | +// Default options |
| 57 | +const n = new npyjs(); |
| 58 | + |
| 59 | +// Disable float16→float32 conversion |
| 60 | +const n2 = new npyjs({ convertFloat16: false }); |
49 | 61 |
|
50 | | -```javascript |
51 | | -n.load("test.npy").then((res) => { |
52 | | - // res has { data, shape, dtype } members. |
53 | | -}); |
| 62 | +const arr = await n.load("my-array.npy"); |
54 | 63 | ``` |
55 | 64 |
|
56 | | -```javascript |
57 | | -const npyArray = await n.load("test.npy"); |
| 65 | +--- |
| 66 | + |
| 67 | +## Accessing multidimensional elements |
| 68 | + |
| 69 | +`npyjs` returns flat typed arrays with a `shape`. `npyjs` also ships a small helper to turn the flat `data` + `shape` into nested JS arrays. |
| 70 | + |
| 71 | +```ts |
| 72 | +import { load } from "npyjs"; |
| 73 | +import { reshape } from "npyjs/reshape"; |
| 74 | + |
| 75 | +const { data, shape, fortranOrder } = await load("my-array.npy"); |
| 76 | +const nested = reshape(data, shape, fortranOrder); // -> arrays nested by dims |
58 | 77 | ``` |
59 | 78 |
|
60 | | -## Accessing multidimensional array elements |
| 79 | +For C-order arrays (the NumPy default), pass fortranOrder = false (default). |
| 80 | + |
| 81 | +For Fortran-order arrays, pass true and the helper will return the natural row-major nested structure. |
61 | 82 |
|
62 | | -- You can conveniently access multidimensional array elements using the 'ndarray' library: |
| 83 | +Or pair it with [ndarray](https://github.com/scijs/ndarray) or TensorFlow\.js: |
63 | 84 |
|
64 | | -```javascript |
| 85 | +```ts |
65 | 86 | import ndarray from "ndarray"; |
66 | | -const npyArray = ndarray(data, shape); |
67 | | -npyArray.get(10, 15); |
| 87 | +import { load } from "npyjs"; |
| 88 | + |
| 89 | +const { data, shape } = await load("my-array.npy"); |
| 90 | +const tensor = ndarray(data, shape); |
| 91 | + |
| 92 | +console.log(tensor.get(10, 15)); |
68 | 93 | ``` |
69 | 94 |
|
70 | | -## Supported Data Types |
| 95 | +--- |
71 | 96 |
|
72 | | -The library supports the following NumPy data types: |
| 97 | +## Supported Data Types |
73 | 98 |
|
74 | 99 | - `int8`, `uint8` |
75 | 100 | - `int16`, `uint16` |
76 | 101 | - `int32`, `uint32` |
77 | | -- `int64`, `uint64` (as BigInt) |
| 102 | +- `int64`, `uint64` (as `BigInt`) |
78 | 103 | - `float32` |
79 | 104 | - `float64` |
80 | 105 | - `float16` (converted to float32 by default) |
81 | 106 |
|
82 | | -### Float16 Support |
| 107 | +### Float16 Control |
83 | 108 |
|
84 | | -By default, float16 arrays are automatically converted to float32 for compatibility, since JavaScript doesn't natively support float16. You can control this behavior with the constructor options: |
85 | | - |
86 | | -```javascript |
87 | | -// Default behavior - float16 is converted to float32 |
| 109 | +```ts |
| 110 | +// Default: converts float16 → float32 |
88 | 111 | const n1 = new npyjs(); |
89 | | -// Keep float16 as raw uint16 values without conversion |
| 112 | + |
| 113 | +// Keep raw Uint16Array |
90 | 114 | const n2 = new npyjs({ convertFloat16: false }); |
91 | 115 | ``` |
92 | 116 |
|
93 | | -Unless otherwise specified, all code inside of this repository is covered under the license in [LICENSE](LICENSE). |
| 117 | +--- |
| 118 | + |
| 119 | +## Development |
| 120 | + |
| 121 | +- Built with [tsup](https://github.com/egoist/tsup) (dual ESM + CJS + d.ts) |
| 122 | +- Tested with [Vitest](https://vitest.dev) |
| 123 | +- CI on GitHub Actions (Node 18/20/22) |
| 124 | + |
| 125 | +### Commands |
| 126 | + |
| 127 | +```bash |
| 128 | +npm run build # Build to dist/ |
| 129 | +npm test # Run Vitest |
| 130 | +npm run typecheck # TypeScript type checking |
| 131 | +``` |
| 132 | + |
| 133 | +--- |
| 134 | + |
| 135 | +## License |
94 | 136 |
|
95 | | -Please report bugs or contribute pull-requests on [GitHub](https://github.com/aplbrain/npyjs). |
| 137 | +Apache-2.0 © [JHU APL](http://www.jhuapl.edu/) |
96 | 138 |
|
97 | 139 | --- |
98 | 140 |
|
99 | 141 | <p align="center"><small>Made with ♥ at <a href="http://www.jhuapl.edu/"><img alt="JHU APL" align="center" src="./docs/apl-logo.png" height="23px"></a></small></p> |
| 142 | +```` |
0 commit comments