# Notable differences with numpy APIs¶

xtensor and numpy are very different libraries in their internal semantics. While xtensor is a lazy expression system, Numpy manipulates in-memory containers, however, similarities in APIs are obvious. See e.g. the numpy to xtensor cheat sheet.

And this page tracks the subtle differences of behavior of numpy and xtensor.

## Zero-dimensional arrays¶

With numpy, 0-D arrays are nearly indistinguishable from scalars. This led to some issues w.r.t. universal functions returning scalars with 0-D array inputs instead of actual arrays...

In xtensor, 0-D expressions are not implicitely convertible to scalar values. Values held by 0-D
expressions can be accessed in the same way as values of higher dimensional arrays, that is with
`operator[]`

, `operator()`

and `element`

.

## Meshgrid¶

Numpy’s version of meshgrid supports two modes: the ‘xy’ indexing and the ‘ij’ indexing.

The following code

```
import numpy as np
x1, x2, x3, x4 = [1], [10, 20], [100, 200, 300], [1000, 2000, 3000, 4000]
ij = np.meshgrid(x1, x2, x3, x4, indexing='ij')
xy = np.meshgrid(x1, x2, x3, x4, indexing='xy')
print 'ij:', [m.shape for m in ij]
print 'xy:', [m.shape for m in xy]
```

would return

```
ij: [(1, 2, 3, 4), (1, 2, 3, 4), (1, 2, 3, 4), (1, 2, 3, 4)]
xy: [(2, 1, 3, 4), (2, 1, 3, 4), (2, 1, 3, 4), (2, 1, 3, 4)]
```

In other words, the ‘xy’ indexing, which is the default only reverses the first two dimensions compared to the ‘ij’ indexing.

xtensor’s version of meshgrid corresponds to the ‘ij’ indexing.

## The random module¶

Like most functions of xtensor, functions of the random module return expressions that don’t hold any value.

Every time an element is accessed, a new random value is generated. To fix the values of a generator, it should be assigned to a container such as xarray or xtensor.