# 2. Manipulate data with `ndarray`

¶

We’ll start by introducing the `NDArray`

, MXNet’s primary tool for
storing and transforming data. If you’ve worked with `NumPy`

before,
you’ll notice that a NDArray is, by design, similar to NumPy’s
multi-dimensional array.

## 2.1. Get started¶

To get started, let’s import the `ndarray`

package (`nd`

is
shortform) from MXNet.

```
In [1]:
```

```
# Uncomment the following line to install the latest MXNet
# !pip install --pre mxnet
# Or use the following version to accelerate Intel CPU performance.
# !pip install --pre mxnet-mkl
from mxnet import nd
```

Next, let’s see how to create a 2D array (also called a matrix) with values from two sets of numbers: 1, 2, 3 and 4, 5, 6. This might also be referred to as a tuple of a tuple of integers.

```
In [2]:
```

```
nd.array(((1,2,3),(5,6,7)))
```

```
Out[2]:
```

```
[[ 1. 2. 3.]
[ 5. 6. 7.]]
<NDArray 2x3 @cpu(0)>
```

We can also create a very simple matrix with the same shape (2 rows by 3 columns), but fill it with 1s.

```
In [3]:
```

```
x = nd.ones((2,3))
x
```

```
Out[3]:
```

```
[[ 1. 1. 1.]
[ 1. 1. 1.]]
<NDArray 2x3 @cpu(0)>
```

Often we’ll want to create arrays whose values are sampled randomly. For example, sampling values uniformly between -1 and 1. Here we create the same shape, but with random sampling.

```
In [4]:
```

```
y = nd.random.uniform(-1,1,(2,3))
y
```

```
Out[4]:
```

```
[[ 0.09762704 0.18568921 0.43037868]
[ 0.68853152 0.20552671 0.71589124]]
<NDArray 2x3 @cpu(0)>
```

You can also fill an array of a given shape with a given value, such as
`2.0`

.

```
In [5]:
```

```
x = nd.full((2,3), 2.0)
x
```

```
Out[5]:
```

```
[[ 2. 2. 2.]
[ 2. 2. 2.]]
<NDArray 2x3 @cpu(0)>
```

As with NumPy, the dimensions of each NDArray are accessible by
accessing the `.shape`

attribute. We can also query its `size`

,
which is equal to the product of the components of the shape. In
addition, `.dtype`

tells the data type of the stored values.

```
In [6]:
```

```
(x.shape, x.size, x.dtype)
```

```
Out[6]:
```

```
((2, 3), 6, numpy.float32)
```

## 2.2. Operations¶

NDArray supports a large number of standard mathematical operations. Such as element-wise multiplication:

```
In [7]:
```

```
x * y
```

```
Out[7]:
```

```
[[ 0.19525409 0.37137842 0.86075735]
[ 1.37706304 0.41105342 1.43178248]]
<NDArray 2x3 @cpu(0)>
```

Exponentiation:

```
In [8]:
```

```
y.exp()
```

```
Out[8]:
```

```
[[ 1.10255146 1.20404804 1.53783977]
[ 1.99078989 1.22817183 2.0460093 ]]
<NDArray 2x3 @cpu(0)>
```

And grab a matrix’s transpose to compute a proper matrix-matrix product:

```
In [9]:
```

```
nd.dot(x, y.T)
```

```
Out[9]:
```

```
[[ 1.42738986 3.21989894]
[ 1.42738986 3.21989894]]
<NDArray 2x2 @cpu(0)>
```

## 2.3. Indexing¶

MXNet NDArrays support slicing in all the ridiculous ways you might
imagine accessing your data. Here’s an example of reading a particular
element, which returns a 1D array with shape `(1,)`

.

```
In [10]:
```

```
y[1,2]
```

```
Out[10]:
```

```
[ 0.71589124]
<NDArray 1 @cpu(0)>
```

Read the second and third columns from `y`

.

```
In [11]:
```

```
y[:,1:3]
```

```
Out[11]:
```

```
[[ 0.18568921 0.43037868]
[ 0.20552671 0.71589124]]
<NDArray 2x2 @cpu(0)>
```

and writing to a specific element

```
In [12]:
```

```
y[:,1:3] = 2
y
```

```
Out[12]:
```

```
[[ 0.09762704 2. 2. ]
[ 0.68853152 2. 2. ]]
<NDArray 2x3 @cpu(0)>
```

Multi-dimensional slicing is also supported.

```
In [13]:
```

```
y[1:2,0:2] = 4
y
```

```
Out[13]:
```

```
[[ 0.09762704 2. 2. ]
[ 4. 4. 2. ]]
<NDArray 2x3 @cpu(0)>
```

## 2.4. Converting between MXNet NDArray and NumPy¶

Converting MXNet NDArrays to and from NumPy is easy. The converted arrays do not share memory.

```
In [14]:
```

```
a = x.asnumpy()
(type(a), a)
```

```
Out[14]:
```

```
(numpy.ndarray, array([[ 2., 2., 2.],
[ 2., 2., 2.]], dtype=float32))
```

```
In [15]:
```

```
nd.array(a)
```

```
Out[15]:
```

```
[[ 2. 2. 2.]
[ 2. 2. 2.]]
<NDArray 2x3 @cpu(0)>
```