Skip to content

Converting numpy arrays

Momtchil Momtchev edited this page Feb 7, 2023 · 3 revisions

Converting between numpy ndarrays and scijs/@stdlib ndarrays

In order to avoid unnecessary dependencies, pymport does not include built-in primitives for converting between Python (numpy) and JavaScript (scijs or @stdlib) arrays. The conversions are very straightforward to implement.

All examples suppose that you use proxified numpy as np:

import { pymport } from 'pymport/proxified';
const np = pymport('numpy');

scijs (npm package ndarray)

From Python to JavaScript

// Let a be a 2D numpy array, two rows, three elements, consecutive values
const a = np.arange(6, {dtype: np.int32}).reshape(2, 3);

// Conversion by copying values (slower but doesn't need to match the type)
const copy1 = ndarray(a.flatten().tolist().toJS(), a.shape.toJS());

// Conversion by copying the backing store (faster, but needs to match the type)
const copy2 = ndarray(new Int32Array(a.toJS().buffer), a.shape.toJS());

Sharing a memory buffer allocated in Python to V8 is currently impossible to implement in all cases due to a V8 limitation: https://github.com/nodejs/node/issues/32463.

From JavaScript to Python

// Let b be a 2D scijs ndarray
const b = ndarray(new Int32Array(6), [2, 3]);

// Conversion by copying the backing store
const copy = np.frombuffer(PyObject.bytes(b.data),
  {dtype: np.int32}).reshape(b.shape);

// Conversion by sharing the same backing store
const ref = np.frombuffer(PyObject.memoryview(b.data),
  {dtype: np.int32}).reshape(b.shape);

@stdlib/ndarray

From Python to JavaScript

const a = np.arange(6, {dtype: np.int32}).reshape(2, 3);

// Conversion by copying values
const copy1 = array(a.flatten().tolist().toJS(), {shape: a.shape.toJS()});

// Conversion by copying the backing store
const copy2 = array(new Int32Array(a.toJS().buffer), {shape: a.shape.toJS()});

From JavaScript to Python

// Let c be a 2D @stdlib/ndarray
const c = array(new Int32Array(6), {shape: [2, 3]});

// Conversion by copying the backing store
const copy = np.frombuffer(PyObject.bytes(c.data),
  {dtype: np.int32}).reshape(c.shape);

// Conversion by sharing the same backing store
const ref = np.frombuffer(PyObject.memoryview(c.data),
  {dtype: np.int32}).reshape(c.shape);

Raw JavaScript TypedArray / Raw JavaScript Array

From Python to JavaScript

const a = np.arange(6, {dtype: np.int32});

// Conversion to a normal JavaScript array
const array = a.flatten().tolist().toJS();

// Conversion to a TypedArray
const typedarray = new Int32Array(a.toJS().buffer);

From JavaScript to Python

// Let d be a TypedArray
const d = new Int32Array(6);

// Conversion by copying the backing store
const copy = np.frombuffer(PyObject.bytes(d.data),
  {dtype: np.int32});

// Conversion by sharing the same backing store
const ref = np.frombuffer(PyObject.memoryview(d.data),
  {dtype: np.int32});