README
xndarray
Multidimensional arrays with semantics in JavaScript.
Introduction
Install
xndarray works on browsers and any tool following the CommonJS/node module conventions.
A minified browser version of this library is available in the GitHub releases and can be included like that:
<script src="xndarray.min.js"></script>
<script>
var arr = xndarray(...)
</script>
API
If you use xndarray within a CommonJS/node environment, then import the constructor as follows:
var xndarray = require('xndarray')
When using the minified browser version, then this constructor is made available globally under the same name.
Constructor
xndarray(data, {shape, names, coords, stride, offset})
data
is a 1D array storage. It is either an instance ofArray
, a typed array, or an object that implementsget()
,set()
,.length
shape
is the shape of the view as an array of integers (Default:[data.length]
)names
is an array of dimension names (Default:['dim_0','dim_1',...]
)coords
is a coordinates map of 1D array storages. Each key is a (dimension) name and each value is either an instance ofArray
, a typed array, an ndarray, or an object that implementsget()
,set()
,.length
(Default:{dim_0: [0,1,2,...], dim_1: [0,1,2,...],...}
)stride
is the resulting stride of the view. (Default: row major)offset
is the offset to start the view (Default: 0)
var arr = xndarray([1,2,3,4,5,6], {
shape: [2,3],
names: ['y','x'],
coords: {
y: [10,12,14],
x: [100,101,102],
t: [new Date('2001-01-01')]
}
})
// arr == 1 2 3
// 4 5 6
In the example, there are coordinates for the y
and x
dimensions plus an extra coordinate named t
.
Extra coordinates are ignored in operations like slicing and carried over unchanged.
xndarray(ndarr, {names, coords})
This constructor variant wraps existing ndarray objects.
ndarr
is an ndarray object.names
is an array of dimension names (Default:['dim_0','dim_1',...]
)coords
is a coordinates map of 1D array storages. Each key is a (dimension) name and each value is either an instance ofArray
, a typed array, an ndarray, or an object that implementsget()
,set()
,.length
(Default:{dim_0: [0,1,2,...], dim_1: [0,1,2,...],...}
)
xndarray is fully compatible with ndarray and can directly wrap such objects:
var nd = ndarray([1,2,3,4], [2,2])
var xnd = xndarray(nd, {
names: ['y','x'],
coords: {
y: [10,12,14],
x: [100,101,102],
t: [new Date('2001-01-01')]
}
})
All ndarray modules can directly be used on xndarray objects:
var unpack = require('ndarray-unpack')
var nd2 = unpack(xnd) // [[1,2],[3,4]]
ndarray functions that return a new ndarray object will not have any xndarray functionality and have to be wrapped again.
Members
Members originating from ndarray:
array.data
- The underlying 1D storage for the multidimensional arrayarray.shape
- The shape of the arrayarray.dimension
- Dimension of the array as an integer (equalsarray.shape.length
)array.size
- Size of the array in logical elements (equalsarray.shape[0]*array.shape[1]*...
)array.stride
- The layout of the array in memoryarray.offset
- The starting offset of the array in memoryarray.dtype
- String representing the underlying data typearray.order
- Order of the stride of the array, sorted in ascending length
Additional members:
array.names
- The dimension names. A string array of lengtharray.dimension
.array.coords
- The coordinates. A Map from (dimension) name to 1D ndarrays.
Element access
/ array.get(i,j,...)array.xget({x: i, y: j, ...})
var arr = xndarray([1,2,3,4,5,6], {shape: [2,3], names: ['y','x']})
// arr.get(0, 1)
var v = arr.xget({y: 0, x: 1})
// v == 2
/ array.set(i,j,...,v)array.xset({x: i, y: j, ...}, v)
var arr = xndarray([1,2,3,4,5,6], {shape: [2,3], names: ['y','x']})
// arr.set(1, 1, 8)
arr.xset({y: 1, x: 1}, 8)
// arr == 1 2 3
// 4 8 6
/ array.index(i,j,...)array.xindex({x: i, y: j, ...})
var arr = xndarray([1,2,3,4,5,6], {shape: [2,3], names: ['y','x']})
// arr.index(1, 0)
var idx = arr.xindex({y: 1, x: 0})
// idx == 3
Slicing
/ array.lo(i,j,...)array.xlo({x: i, y: j, ...})
var arr = xndarray([1,2,3,4,5,6], {
shape: [2,3],
names: ['y','x'],
coords: {
y: [10,12,14],
x: [100,101,102]
}
})
// arr == 1 2 3
// 4 5 6
// arr.lo(null, 1)
var a = arr.xlo({x: 1})
// a == 2 3
// 5 6
// a.coords.get('y') == 10 12 14
// a.coords.get('x') == 101 102
/ array.hi(i,j,...)array.xhi({x: i, y: j, ...})
var arr = xndarray([1,2,3,4,5,6], {
shape: [2,3],
names: ['y','x'],
coords: {
y: [10,12,14],
x: [100,101,102]
}
})
// arr.hi(null, 2)
var a = arr.xhi({x: 2})
// a == 1 2
// 4 5
// a.coords.get('y') == 10 12 14
// a.coords.get('x') == 100 101
/ array.step(i,j,...)array.xstep({x: i, y: j, ...})
var arr = xndarray([1,2,3,4,5,6], {
shape: [2,3],
names: ['y','x'],
coords: {
y: [10,12,14],
x: [100,101,102]
}
})
// arr.step(null, 2)
var a = arr.xstep({x: 2})
// a == 1 3
// 4 6
// a.coords.get('y') == 10 12 14
// a.coords.get('x') == 100 102
/ array.transpose(p0, p1, ...)array.xtranspose('x','y',...)
The transpose/xtranspose functions change the axis order. This has no relevance if you only work with x-prefixed functions since they work directly on axis names.
var arr = xndarray([1,2,3,4,5,6], {shape: [2,3], names: ['y','x']})
// arr.transpose(1, 0)
var a = arr.xtranspose('x', 'y')
// a == 1 4
// 2 5
// 3 6
//
// a.names == ['x','y']
/ array.pick(i,j,...)array.xpick({x: i, y: j, ...})
var arr = xndarray([1,2,3,4,5,6], {
shape: [2,3],
names: ['y','x'],
coords: {
y: [10,12,14],
x: [100,101,102]
}
})
// arr.pick(null, 1)
var a = arr.xpick({x: 1})
// a == 2 5
// a.dimension == 1
// a.names == ['y']
// a.coords.get('y') == 10 12 14
// a.coords.get('x') == 101
Note that the x
coordinates get reduced to a single value in the example.
Acknowledgments
This library is inspired by the Python packages PyHRF (see pyhrf.ndarray.xndarray class) and xarray. It is based on and compatible with the ndarray JavaScript library.