[−][src]Module ndarray::doc::ndarray_for_numpy_users
ndarray
for NumPy users.
This is an introductory guide to ndarray
for people with experience using
NumPy, although it may also be useful to others. For a more general
introduction to ndarray
's array type ArrayBase
, see the ArrayBase
docs.
Contents
Similarities
ndarray
's array type (ArrayBase
), is very similar to
NumPy's array type (numpy.ndarray
):
 Arrays have a single element type.
 Arrays can have arbitrarily many dimensions.
 Arrays can have arbitrary strides.
 Indexing starts at zero, not one.
 The default memory layout is rowmajor, and the default iterators follow rowmajor order (also called "logical order" in the documentation).
 Arithmetic operators work elementwise. (For example,
a * b
performs elementwise multiplication, not matrix multiplication.)  Owned arrays are contiguous in memory.
 Many operations, such as slicing, are very cheap because they can return a view of an array instead of copying the data.
NumPy has many features that ndarray
doesn't have yet, such as:
 index arrays
 mask index arrays
 cobroadcasting (
ndarray
only supports broadcasting the righthand array in a binary operation.)
Some key differences
NumPy 


In NumPy, there is no distinction between owned arrays, views, and mutable
views. There can be multiple arrays (instances of 
In 
In NumPy, all arrays are dynamicdimensional. 
In 
When slicing in NumPy, the indices are 
When slicing in 
The ndarray ecosystem
ndarray
does not provide advanced linear algebra routines out of the box (e.g. SVD decomposition).
Most of the routines that you can find in scipy.linalg
/numpy.linalg
are provided by another crate,
ndarraylinalg
.
The same holds for statistics: ndarray
provides some basic functionalities (e.g. mean
)
but more advanced routines can be found in ndarraystats
.
If you are looking to generate random arrays instead, check out ndarrayrand
.
It is also possible to serialize NumPy
arrays in .npy
/.npz
format and deserialize them as ndarray
arrays (and vice versa)
using ndarraynpy
.
Other Rust array/matrix crates
Of the array/matrix types in Rust crates, the ndarray
array type is probably
the most similar to NumPy's arrays and is the most flexible. However, if your
usecase is constrained to linear algebra on 1D and 2D vectors and matrices,
it might be worth considering other crates:
nalgebra
provides 1D and 2D columnmajor vector and matrix types for linear algebra. Vectors and matrices can have constant or dynamic shapes, andnalgebra
uses the type system to provide compiletime checking of shapes, not just the number of dimensions.nalgebra
provides convenient functionality for geometry (e.g. coordinate transformations) and linear algebra.cgmath
provides 1D and 2D columnmajor types of shape 4×4 or smaller. It's primarily designed for computer graphics and provides convenient functionality for geometry (e.g. coordinate transformations). Similar tonalgebra
,cgmath
uses the type system to provide compiletime checking of shapes.rulinalg
provides 1D and 2D rowmajor vector and matrix types with dynamic shapes. Similar tondarray
,rulinalg
provides compiletime checking of the number of dimensions, but not shapes.rulinalg
provides pureRust implementations of linear algebra operations. If there's another crate that should be listed here, please let us know.
In contrast to these crates, ndarray
provides an ndimensional array type,
so it's not restricted to 1D and 2D vectors and matrices. Also, operators
operate elementwise by default, so the multiplication operator *
performs
elementwise multiplication instead of matrix multiplication. (You have to
specifically call .dot()
if you want matrix multiplication.)
Rough ndarray
–NumPy equivalents
These tables provide some rough equivalents of NumPy operations in ndarray
.
There are a variety of other methods that aren't included in these tables,
including shapemanipulation, array creation, and iteration routines.
It's assumed that you've imported NumPy like this:
import numpy as np
and ndarray
like this:
use ndarray::prelude::*;
Array creation
This table contains ways to create arrays from scratch. For creating arrays by
operations on other arrays (e.g. arithmetic), see the other tables. Also see
the ::from_vec()
, ::from_iter()
,
::default()
, ::from_shape_fn()
, and
::from_shape_vec_unchecked()
methods.
NumPy  ndarray  Notes 

np.array([[1.,2.,3.], [4.,5.,6.]])  array![[1.,2.,3.], [4.,5.,6.]] or arr2(&[[1.,2.,3.], [4.,5.,6.]])  2×3 floatingpoint array literal 
np.arange(0., 10., 0.5) or np.r_[:10.:0.5]  Array::range(0., 10., 0.5)  create a 1D array with values 0. , 0.5 , …, 9.5 
np.linspace(0., 10., 11) or np.r_[:10.:11j]  Array::linspace(0., 10., 11)  create a 1D array with 11 elements with values 0. , …, 10. 
np.logspace(2.0, 3.0, num=4, base=10.0)  Array::logspace(10.0, 2.0, 3.0, 4)  create a 1D array with 4 elements with values 100. , 215.4 , 464.1 , 1000. 
np.geomspace(1., 1000., num=4)  Array::geomspace(1e0, 1e3, 4)  create a 1D array with 4 elements with values 1. , 10. , 100. , 1000. 
np.ones((3, 4, 5))  Array::ones((3, 4, 5))  create a 3×4×5 array filled with ones (inferring the element type) 
np.zeros((3, 4, 5))  Array::zeros((3, 4, 5))  create a 3×4×5 array filled with zeros (inferring the element type) 
np.zeros((3, 4, 5), order='F')  Array::zeros((3, 4, 5).f())  create a 3×4×5 array with Fortran (columnmajor) memory layout filled with zeros (inferring the element type) 
np.zeros_like(a, order='C')  Array::zeros(a.raw_dim())  create an array of zeros of the shape shape as a , with rowmajor memory layout (unlike NumPy, this infers the element type from context instead of duplicating a 's element type) 
np.full((3, 4), 7.)  Array::from_elem((3, 4), 7.)  create a 3×4 array filled with the value 7. 
np.eye(3)  Array::eye(3)  create a 3×3 identity matrix (inferring the element type) 
np.diag(np.array([1, 2, 3]))  Array2::from_diag(&arr1(&[1, 2, 3]))  create a 3×3 matrix with [1, 2, 3] as diagonal and zeros elsewhere (inferring the element type) 
np.array([1, 2, 3, 4]).reshape((2, 2))  Array::from_shape_vec((2, 2), vec![1, 2, 3, 4])?  create a 2×2 array from the elements in the list/Vec 
np.array([1, 2, 3, 4]).reshape((2, 2), order='F')  Array::from_shape_vec((2, 2).f(), vec![1, 2, 3, 4])?  create a 2×2 array from the elements in the list/Vec using Fortran (columnmajor) order 
np.random  See the ndarrayrand crate.  create arrays of random numbers 
Note that the examples in the table rely on the compiler inferring the
element type and dimensionality from context, which is usually sufficient.
However, if the compiler cannot infer the types, you can specify them
manually. These are examples of creating a 3D Fortranlayout array of
f64
s:
// This is an example where the compiler can infer the element type // because `f64::sin` can only be called on `f64` elements: let arr1 = Array::zeros((3, 2, 4).f()); arr1.mapv(f64::sin); // Specify just the element type and infer the dimensionality: let arr2 = Array::<f64, _>::zeros((3, 2, 4).f()); let arr3: Array<f64, _> = Array::zeros((3, 2, 4).f()); // Specify both the element type and dimensionality: let arr4 = Array3::<f64>::zeros((3, 2, 4).f()); let arr5: Array3<f64> = Array::zeros((3, 2, 4).f()); let arr6 = Array::<f64, Ix3>::zeros((3, 2, 4).f()); let arr7: Array<f64, Ix3> = Array::zeros((3, 2, 4).f());
Indexing and slicing
A few notes:

Indices start at 0. For example, "row 1" is the second row in the array.

Some methods have multiple variants in terms of ownership and mutability. Only the nonmutable methods that take the array by reference are listed in this table. For example,
.slice()
also has corresponding methods.slice_mut()
,.slice_move()
, and.slice_collapse()
. 
The behavior of slicing is slightly different from NumPy for slices with
step < 1
. See the docs for thes![]
macro for more details.
NumPy  ndarray  Notes 

a[1]  a[a.len()  1]  access the last element in 1D array a 
a[1, 4]  a[[1, 4]]  access the element in row 1, column 4 
a[1] or a[1, :, :]  a.slice(s![1, .., ..]) or a.index_axis(Axis(0), 1)  get a 2D subview of a 3D array at index 1 of axis 0 
a[0:5] or a[:5] or a[0:5, :]  a.slice(s![0..5, ..]) or a.slice(s![..5, ..]) or a.slice_axis(Axis(0), Slice::from(0..5))  get the first 5 rows of a 2D array 
a[5:] or a[5:, :]  a.slice(s![5.., ..]) or a.slice_axis(Axis(0), Slice::from(5..))  get the last 5 rows of a 2D array 
a[:3, 4:9]  a.slice(s![..3, 4..9])  columns 4, 5, 6, 7, and 8 of the first 3 rows 
a[1:4:2, ::1]  a.slice(s![1..4;2, ..;1])  rows 1 and 3 with the columns in reverse order 
Shape and strides
Note that a.shape()
, a.dim()
, and
a.raw_dim()
all return the shape of the array, but as
different types. a.shape()
returns the shape as &[Ix]
, (where
Ix
is usize
) which is useful for general operations on the shape.
a.dim()
returns the shape as D::Pattern
, which is useful for
patternmatching shapes. a.raw_dim()
returns the shape as D
, which is
useful for creating other arrays of the same shape.
NumPy  ndarray  Notes 

np.ndim(a) or a.ndim  a.ndim()  get the number of dimensions of array a 
np.size(a) or a.size  a.len()  get the number of elements in array a 
np.shape(a) or a.shape  a.shape() or a.dim()  get the shape of array a 
a.shape[axis]  a.len_of(Axis(axis))  get the length of an axis 
a.strides  a.strides()  get the strides of array a 
np.size(a) == 0 or a.size == 0  a.is_empty()  check if the array has zero elements 
Mathematics
Note that .mapv()
has corresponding methods .map()
,
.mapv_into()
, .map_inplace()
, and
.mapv_inplace()
. Also look at .fold()
,
.visit()
, .fold_axis()
, and
.map_axis()
.
NumPy 

Notes 


transpose of array  

2D matrix multiply  

2D matrix dot 1D column vector  

1D row vector dot 2D matrix  

vector dot product  

elementwise arithmetic operations  

elementwise power of 3  

elementwise square root for  

array of  

sum the elements in  

sum the elements in  

calculate the mean of the elements in  

calculate the mean of the elements in  

check if the arrays' elementwise differences are within an absolute tolerance (it requires the  

view the diagonal of  

See 
linear algebra (matrix inverse, solving, decompositions, etc.) 
Array manipulation
NumPy  ndarray  Notes 

a[:] = 3.  a.fill(3.)  set all array elements to the same scalar value 
a[:] = b  a.assign(&b)  copy the data from array b into array a 
np.concatenate((a,b), axis=1)  stack![Axis(1), a, b] or stack(Axis(1), &[a.view(), b.view()])  concatenate arrays a and b along axis 1 
np.stack((a,b), axis=1)  stack_new_axis![Axis(1), a, b] or stack_new_axis(Axis(1), vec![a.view(), b.view()])  stack arrays a and b along axis 1 
a[:,np.newaxis] or np.expand_dims(a, axis=1)  a.insert_axis(Axis(1))  create an array from a , inserting a new axis 1 
a.transpose() or a.T  a.t() or a.reversed_axes()  transpose of array a (view for .t() or bymove for .reversed_axes() ) 
np.diag(a)  a.diag()  view the diagonal of a 
a.flatten()  use std::iter::FromIterator; Array::from_iter(a.iter().cloned())  create a 1D array by flattening a 
Iteration
ndarray
has lots of interesting iterators/producers that implement the
NdProducer
trait, which is a generalization of Iterator
to multiple dimensions. This makes it possible to correctly and efficiently
zip together slices/subviews of arrays in multiple dimensions with
Zip
or azip!()
. The purpose of this is similar to
np.nditer
,
but Zip
is implemented and used somewhat differently.
This table lists some of the iterators/producers which have a direct
equivalent in NumPy. For a more complete introduction to producers and
iterators, see Loops, Producers, and
Iterators.
Note that there are also variants of these iterators (with a _mut
suffix)
that yield ArrayViewMut
instead of ArrayView
.
NumPy  ndarray  Notes 

a.flat  a.iter()  iterator over the array elements in logical order 
np.ndenumerate(a)  a.indexed_iter()  flat iterator yielding the index along with each element reference 
iter(a)  a.outer_iter() or a.axis_iter(Axis(0))  iterator over the first (outermost) axis, yielding each subview 
Convenience methods for 2D arrays
NumPy  ndarray  Notes 

len(a) or a.shape[0]  a.nrows()  get the number of rows in a 2D array 
a.shape[1]  a.ncols()  get the number of columns in a 2D array 
a[1] or a[1,:]  a.row(1) or a.row_mut(1)  view (or mutable view) of row 1 in a 2D array 
a[:,4]  a.column(4) or a.column_mut(4)  view (or mutable view) of column 4 in a 2D array 
a.shape[0] == a.shape[1]  a.is_square()  check if the array is square 
Modules
coord_transform  Example of rotation with Euler angles. 
rk_step  Example of translating 
simple_math  Example of simple math operations on 2D arrays. 