|
1 | 1 | //! `ndarray` for NumPy users.
|
2 | 2 | //!
|
3 |
| -//! `ndarray`'s array type ([`ArrayBase`](../../struct.ArrayBase.html)), is |
4 |
| -//! very similar to NumPy's array type (`numpy.ndarray`): |
| 3 | +//! This is an introductory guide to `ndarray` for people with experience using |
| 4 | +//! NumPy, although it may also be useful to others. For a more general |
| 5 | +//! introduction to `ndarray`'s array type `ArrayBase`, see the [`ArrayBase` |
| 6 | +//! docs][ArrayBase]. |
| 7 | +//! |
| 8 | +//! # Contents |
| 9 | +//! |
| 10 | +//! * [Similarities](#similarities) |
| 11 | +//! * [Some key differences](#some-key-differences) |
| 12 | +//! * [Other Rust array/matrix crates](#other-rust-arraymatrix-crates) |
| 13 | +//! * [Rough `ndarray`–NumPy equivalents](#rough-ndarraynumpy-equivalents) |
| 14 | +//! |
| 15 | +//! * [Array creation](#array-creation) |
| 16 | +//! * [Indexing and slicing](#indexing-and-slicing) |
| 17 | +//! * [Shape and strides](#shape-and-strides) |
| 18 | +//! * [Mathematics](#mathematics) |
| 19 | +//! * [Array manipulation](#array-manipulation) |
| 20 | +//! * [Iteration](#iteration) |
| 21 | +//! * [Convenience methods for 2-D arrays](#convenience-methods-for-2-d-arrays) |
| 22 | +//! |
| 23 | +//! # Similarities |
| 24 | +//! |
| 25 | +//! `ndarray`'s array type ([`ArrayBase`][ArrayBase]), is very similar to |
| 26 | +//! NumPy's array type (`numpy.ndarray`): |
5 | 27 | //!
|
6 | 28 | //! * Arrays have a single element type.
|
7 | 29 | //! * Arrays can have arbitrarily many dimensions.
|
|
47 | 69 | //! </td>
|
48 | 70 | //! <td>
|
49 | 71 | //!
|
50 |
| -//! In `ndarray`, all arrays are instances of |
51 |
| -//! [`ArrayBase`](../../struct.ArrayBase.html), but `ArrayBase` is generic over |
52 |
| -//! the ownership of the data. [`Array`](../../type.Array.html) owns its data; |
53 |
| -//! [`ArrayView`](../../type.ArrayView.html) is a view; |
54 |
| -//! [`ArrayViewMut`](../../type.ArrayViewMut.html) is a mutable view; and |
55 |
| -//! [`ArcArray`](../../type.ArcArray.html) has a reference-counted pointer to |
56 |
| -//! its data (with copy-on-write mutation). Arrays and views follow Rust's |
57 |
| -//! aliasing rules. |
| 72 | +//! In `ndarray`, all arrays are instances of [`ArrayBase`][ArrayBase], but |
| 73 | +//! `ArrayBase` is generic over the ownership of the data. [`Array`][Array] |
| 74 | +//! owns its data; [`ArrayView`][ArrayView] is a view; |
| 75 | +//! [`ArrayViewMut`][ArrayViewMut] is a mutable view; and |
| 76 | +//! [`ArcArray`][ArcArray] has a reference-counted pointer to its data (with |
| 77 | +//! copy-on-write mutation). Arrays and views follow Rust's aliasing rules. |
58 | 78 | //!
|
59 | 79 | //! </td>
|
60 | 80 | //! </tr>
|
|
68 | 88 | //! <td>
|
69 | 89 | //!
|
70 | 90 | //! In `ndarray`, you can create fixed-dimension arrays, such as
|
71 |
| -//! [`Array2`](../../type.Array2.html). This takes advantage of the type system |
72 |
| -//! to help you write correct code and also avoids small heap allocations for |
73 |
| -//! the shape and strides. |
| 91 | +//! [`Array2`][Array2]. This takes advantage of the type system to help you |
| 92 | +//! write correct code and also avoids small heap allocations for the shape and |
| 93 | +//! strides. |
74 | 94 | //!
|
75 | 95 | //! </td>
|
76 | 96 | //! </tr>
|
|
164 | 184 | //! `np.array([[1.,2.,3.], [4.,5.,6.]])` | [`array![[1.,2.,3.], [4.,5.,6.]]`][array!] or [`arr2(&[[1.,2.,3.], [4.,5.,6.]])`][arr2()] | 2×3 floating-point array literal
|
165 | 185 | //! `np.arange(0., 10., 0.5)` or `np.r_[:10.:0.5]` | [`Array::range(0., 10., 0.5)`][::range()] | create a 1-D array with values `0.`, `0.5`, …, `9.5`
|
166 | 186 | //! `np.linspace(0., 10., 11)` or `np.r_[:10.:11j]` | [`Array::linspace(0., 10., 11)`][::linspace()] | create a 1-D array with 11 elements with values `0.`, …, `10.`
|
| 187 | +//! `np.ones((3, 4, 5))` | [`Array::ones((3, 4, 5))`][::ones()] | create a 3×4×5 array filled with ones (inferring the element type) |
167 | 188 | //! `np.zeros((3, 4, 5))` | [`Array::zeros((3, 4, 5))`][::zeros()] | create a 3×4×5 array filled with zeros (inferring the element type)
|
168 | 189 | //! `np.zeros((3, 4, 5), order='F')` | [`Array::zeros((3, 4, 5).f())`][::zeros()] | create a 3×4×5 array with Fortran (column-major) memory layout filled with zeros (inferring the element type)
|
| 190 | +//! `np.zeros_like(a, order='C')` | [`Array::zeros(a.raw_dim())`][::zeros()] | create an array of zeros of the shape shape as `a`, with row-major memory layout (unlike NumPy, this infers the element type from context instead of duplicating `a`'s element type) |
169 | 191 | //! `np.full((3, 4), 7.)` | [`Array::from_elem((3, 4), 7.)`][::from_elem()] | create a 3×4 array filled with the value `7.`
|
170 | 192 | //! `np.eye(3)` | [`Array::eye(3)`][::eye()] | create a 3×3 identity matrix (inferring the element type)
|
171 | 193 | //! `np.array([1, 2, 3, 4]).reshape((2, 2))` | [`Array::from_shape_vec((2, 2), vec![1, 2, 3, 4])?`][::from_shape_vec()] | create a 2×2 array from the elements in the list/`Vec`
|
172 | 194 | //! `np.array([1, 2, 3, 4]).reshape((2, 2), order='F')` | [`Array::from_shape_vec((2, 2).f(), vec![1, 2, 3, 4])?`][::from_shape_vec()] | create a 2×2 array from the elements in the list/`Vec` using Fortran (column-major) order
|
173 |
| -//! `np.empty((3, 4))` | [`unsafe { Array::uninitialized((3, 4)) }`][::uninitialized()] | create a 3×4 uninitialized array (inferring the element type) |
174 | 195 | //! `np.random` | See the [`ndarray-rand`](https://crates.io/crates/ndarray-rand) crate. | create arrays of random numbers
|
175 | 196 | //!
|
176 | 197 | //! ## Indexing and slicing
|
|
190 | 211 | //!
|
191 | 212 | //! NumPy | `ndarray` | Notes
|
192 | 213 | //! ------|-----------|------
|
193 |
| -//! `a[-1]` | [`a[a.len()-1]`][.index()] | access the last element in 1-D array `a` |
194 |
| -//! `a[1,4]` | [`a[(1,4)]`][.index()] | access the element in row 1, column 4 |
195 |
| -//! `a[1]` or `a[1,:,:]` | [`a.slice(s![1, .., ..])`][.slice()] or [`a.subview(Axis(0), 1)`][.subview()] | get a 2-D subview of a 3-D array at index 1 of axis 0 |
196 |
| -//! `a[0:5]` or `a[:5]` or `a[0:5,:]` | [`a.slice(s![0..5, ..])`][.slice()] or [`a.slice(s![..5, ..])`][.slice()] or [`a.slice_axis(Axis(0), (0..5).into())`][.slice_axis()] | get the first 5 rows of a 2-D array |
197 |
| -//! `a[-5:]` or `a[-5:,:]` | [`a.slice(s![-5.., ..])`][.slice()] or [`a.slice_axis(Axis(0), (-5..).into())`][.slice_axis()] | get the last 5 rows of a 2-D array |
198 |
| -//! `a[:3,4:9]` | [`a.slice(s![..3, 4..9])`][.slice()] | columns 4, 5, 6, 7, and 8 of the first 3 rows |
199 |
| -//! `a[1:4:2,::-1]` | [`a.slice(s![1..4;2, ..;-1])`][.slice()] | rows 1 and 3 with the columns in reverse order |
| 214 | +//! `a[-1]` | [`a[a.len() - 1]`][.index()] | access the last element in 1-D array `a` |
| 215 | +//! `a[1, 4]` | [`a[[1, 4]]`][.index()] | access the element in row 1, column 4 |
| 216 | +//! `a[1]` or `a[1, :, :]` | [`a.slice(s![1, .., ..])`][.slice()] or [`a.subview(Axis(0), 1)`][.subview()] | get a 2-D subview of a 3-D array at index 1 of axis 0 |
| 217 | +//! `a[0:5]` or `a[:5]` or `a[0:5, :]` | [`a.slice(s![0..5, ..])`][.slice()] or [`a.slice(s![..5, ..])`][.slice()] or [`a.slice_axis(Axis(0), Slice::from(0..5))`][.slice_axis()] | get the first 5 rows of a 2-D array |
| 218 | +//! `a[-5:]` or `a[-5:, :]` | [`a.slice(s![-5.., ..])`][.slice()] or [`a.slice_axis(Axis(0), Slice::from(-5..))`][.slice_axis()] | get the last 5 rows of a 2-D array |
| 219 | +//! `a[:3, 4:9]` | [`a.slice(s![..3, 4..9])`][.slice()] | columns 4, 5, 6, 7, and 8 of the first 3 rows |
| 220 | +//! `a[1:4:2, ::-1]` | [`a.slice(s![1..4;2, ..;-1])`][.slice()] | rows 1 and 3 with the columns in reverse order |
200 | 221 | //!
|
201 | 222 | //! ## Shape and strides
|
202 | 223 | //!
|
| 224 | +//! Note that [`a.shape()`][.shape()], [`a.dim()`][.dim()], and |
| 225 | +//! [`a.raw_dim()`][.raw_dim()] all return the shape of the array, but as |
| 226 | +//! different types. `a.shape()` returns the shape as `&[Ix]`, (where |
| 227 | +//! [`Ix`][Ix] is `usize`) which is useful for general operations on the shape. |
| 228 | +//! `a.dim()` returns the shape as `D::Pattern`, which is useful for |
| 229 | +//! pattern-matching shapes. `a.raw_dim()` returns the shape as `D`, which is |
| 230 | +//! useful for creating other arrays of the same shape. |
| 231 | +//! |
203 | 232 | //! NumPy | `ndarray` | Notes
|
204 | 233 | //! ------|-----------|------
|
205 | 234 | //! `np.ndim(a)` or `a.ndim` | [`a.ndim()`][.ndim()] | get the number of dimensions of array `a`
|
206 | 235 | //! `np.size(a)` or `a.size` | [`a.len()`][.len()] | get the number of elements in array `a`
|
207 | 236 | //! `np.shape(a)` or `a.shape` | [`a.shape()`][.shape()] or [`a.dim()`][.dim()] | get the shape of array `a`
|
208 |
| -//! `a.shape[axis]` | [`a.len_of(Axis(axis))`][.len_of()] or `a.shape()[axis]` | get the length of an axis |
| 237 | +//! `a.shape[axis]` | [`a.len_of(Axis(axis))`][.len_of()] | get the length of an axis |
209 | 238 | //! `a.strides` | [`a.strides()`][.strides()] | get the strides of array `a`
|
210 | 239 | //! `np.size(a) == 0` or `a.size == 0` | [`a.is_empty()`][.is_empty()] | check if the array has zero elements
|
211 | 240 | //!
|
|
242 | 271 | //!
|
243 | 272 | //! </td><td>
|
244 | 273 | //!
|
245 |
| -//! transpose of array `a` |
| 274 | +//! transpose of array `a` (view for `.t()` or by-move for `.reversed_axes()`) |
246 | 275 | //!
|
247 | 276 | //! </td></tr>
|
248 | 277 | //!
|
|
467 | 496 | //! `a[:] = b` | [`a.assign(&b)`][.assign()] | copy the data from array `b` into array `a`
|
468 | 497 | //! `np.concatenate((a,b), axis=1)` | [`stack![Axis(1), a, b]`][stack!] or [`stack(Axis(1), &[a.view(), b.view()])`][stack()] | concatenate arrays `a` and `b` along axis 1
|
469 | 498 | //! `a[:,np.newaxis]` or `np.expand_dims(a, axis=1)` | [`a.insert_axis(Axis(1))`][.insert_axis()] | create an array from `a`, inserting a new axis 1
|
470 |
| -//! `a.transpose()` or `a.T` | [`a.t()`][.t()] or [`a.reversed_axes()`][.reversed_axes()] | transpose of array `a` |
| 499 | +//! `a.transpose()` or `a.T` | [`a.t()`][.t()] or [`a.reversed_axes()`][.reversed_axes()] | transpose of array `a` (view for `.t()` or by-move for `.reversed_axes()`) |
471 | 500 | //! `np.diag(a)` | [`a.diag()`][.diag()] | view the diagonal of `a`
|
472 |
| -//! `a.flat` | [`a.iter()`][.iter()] | iterator over the array elements in logical order |
473 | 501 | //! `a.flatten()` | [`Array::from_iter(a.iter())`][::from_iter()] | create a 1-D array by flattening `a`
|
474 | 502 | //!
|
| 503 | +//! ## Iteration |
| 504 | +//! |
| 505 | +//! `ndarray` has lots of interesting iterators/producers that implement the |
| 506 | +//! [`NdProducer`][NdProducer] trait, which is a generalization of `Iterator` |
| 507 | +//! to multiple dimensions. This makes it possible to correctly and efficiently |
| 508 | +//! zip together slices/subviews of arrays in multiple dimensions with |
| 509 | +//! [`Zip`][Zip] or [`azip!()`][azip!]. The purpose of this is similar to |
| 510 | +//! [`np.nditer`](https://docs.scipy.org/doc/numpy/reference/generated/numpy.nditer.html), |
| 511 | +//! but [`Zip`][Zip] is implemented and used somewhat differently. |
| 512 | +//! |
| 513 | +//! This table lists some of the iterators/producers which have a direct |
| 514 | +//! equivalent in NumPy. For a more complete introduction to producers and |
| 515 | +//! iterators, see [*Loops, Producers, and |
| 516 | +//! Iterators*](../../struct.ArrayBase.html#loops-producers-and-iterators). |
| 517 | +//! Note that there are also variants of these iterators (with a `_mut` suffix) |
| 518 | +//! that yield `ArrayViewMut` instead of `ArrayView`. |
| 519 | +//! |
| 520 | +//! NumPy | `ndarray` | Notes |
| 521 | +//! ------|-----------|------ |
| 522 | +//! `a.flat` | [`a.iter()`][.iter()] | iterator over the array elements in logical order |
| 523 | +//! `np.ndenumerate(a)` | [`a.indexed_iter()`][.indexed_iter()] | flat iterator yielding the index along with each element reference |
| 524 | +//! `iter(a)` | [`a.outer_iter()`][.outer_iter()] or [`a.axis_iter(Axis(0))`][.axis_iter()] | iterator over the first (outermost) axis, yielding each subview |
| 525 | +//! |
475 | 526 | //! ## Convenience methods for 2-D arrays
|
476 | 527 | //!
|
477 | 528 | //! NumPy | `ndarray` | Notes
|
|
483 | 534 | //! `a.shape[0] == a.shape[1]` | [`a.is_square()`][.is_square()] | check if the array is square
|
484 | 535 | //!
|
485 | 536 | //! [.all_close()]: ../../struct.ArrayBase.html#method.all_close
|
486 |
| -//! [array!]: ../../macro.array.html |
| 537 | +//! [ArcArray]: ../../type.ArcArray.html |
487 | 538 | //! [arr2()]: ../../fn.arr2.html
|
| 539 | +//! [array!]: ../../macro.array.html |
| 540 | +//! [Array]: ../../type.Array.html |
| 541 | +//! [Array2]: ../../type.Array2.html |
| 542 | +//! [ArrayBase]: ../../struct.ArrayBase.html |
| 543 | +//! [ArrayView]: ../../type.ArrayView.html |
| 544 | +//! [ArrayViewMut]: ../../type.ArrayViewMut.html |
488 | 545 | //! [.assign()]: ../../struct.ArrayBase.html#method.assign
|
| 546 | +//! [.axis_iter()]: ../../struct.ArrayBase.html#method.axis_iter |
| 547 | +//! [azip!]: ../../macro.azip.html |
489 | 548 | //! [.cols()]: ../../struct.ArrayBase.html#method.cols
|
490 | 549 | //! [.column()]: ../../struct.ArrayBase.html#method.column
|
491 | 550 | //! [.column_mut()]: ../../struct.ArrayBase.html#method.column_mut
|
|
503 | 562 | //! [::from_shape_vec_unchecked()]: ../../struct.ArrayBase.html#method.from_shape_vec_unchecked
|
504 | 563 | //! [::from_vec()]: ../../struct.ArrayBase.html#method.from_vec
|
505 | 564 | //! [.index()]: ../../struct.ArrayBase.html#impl-Index<I>
|
| 565 | +//! [.indexed_iter()]: ../../struct.ArrayBase.html#method.indexed_iter |
506 | 566 | //! [.insert_axis()]: ../../struct.ArrayBase.html#method.insert_axis
|
507 | 567 | //! [.is_empty()]: ../../struct.ArrayBase.html#method.is_empty
|
508 | 568 | //! [.is_square()]: ../../struct.ArrayBase.html#method.is_square
|
509 | 569 | //! [.iter()]: ../../struct.ArrayBase.html#method.iter
|
| 570 | +//! [Ix]: ../../type.Ix.html |
510 | 571 | //! [.len()]: ../../struct.ArrayBase.html#method.len
|
511 | 572 | //! [.len_of()]: ../../struct.ArrayBase.html#method.len_of
|
512 | 573 | //! [::linspace()]: ../../struct.ArrayBase.html#method.linspace
|
|
519 | 580 | //! [matrix-* dot]: ../../struct.ArrayBase.html#method.dot-1
|
520 | 581 | //! [.mean_axis()]: ../../struct.ArrayBase.html#method.mean_axis
|
521 | 582 | //! [.ndim()]: ../../struct.ArrayBase.html#method.ndim
|
| 583 | +//! [NdProducer]: ../../trait.NdProducer.html |
| 584 | +//! [::ones()]: ../../struct.ArrayBase.html#method.ones |
| 585 | +//! [.outer_iter()]: ../../struct.ArrayBase.html#method.outer_iter |
522 | 586 | //! [::range()]: ../../struct.ArrayBase.html#method.range
|
| 587 | +//! [.raw_dim()]: ../../struct.ArrayBase.html#method.raw_dim |
523 | 588 | //! [.reversed_axes()]: ../../struct.ArrayBase.html#method.reversed_axes
|
524 | 589 | //! [.row()]: ../../struct.ArrayBase.html#method.row
|
525 | 590 | //! [.row_mut()]: ../../struct.ArrayBase.html#method.row_mut
|
|
542 | 607 | //! [vec-* dot]: ../../struct.ArrayBase.html#method.dot
|
543 | 608 | //! [.visit()]: ../../struct.ArrayBase.html#method.visit
|
544 | 609 | //! [::zeros()]: ../../struct.ArrayBase.html#method.zeros
|
| 610 | +//! [Zip]: ../../struct.Zip.html |
0 commit comments