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.
Get started¶
To get started, let’s import the ndarray
package (nd
is shortform) from MXNet.
[1]:
# If you hasn't install MXNet yet, you can uncomment the following line to
# install the latest stable release
# !pip install -U mxnet
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.
[2]:
nd.array(((1,2,3),(5,6,7)))
[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.
[3]:
x = nd.ones((2,3))
x
[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.
[4]:
y = nd.random.uniform(-1,1,(2,3))
y
[4]:
[[0.09762704 0.18568921 0.43037868]
[0.6885315 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
.
[5]:
x = nd.full((2,3), 2.0)
x
[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.
[6]:
(x.shape, x.size, x.dtype)
[6]:
((2, 3), 6, numpy.float32)
Operations¶
NDArray supports a large number of standard mathematical operations. Such as element-wise multiplication:
[7]:
x * y
[7]:
[[0.19525409 0.37137842 0.86075735]
[1.377063 0.41105342 1.4317825 ]]
<NDArray 2x3 @cpu(0)>
Exponentiation:
[8]:
y.exp()
[8]:
[[1.1025515 1.204048 1.5378398]
[1.9907899 1.2281718 2.0460093]]
<NDArray 2x3 @cpu(0)>
And grab a matrix’s transpose to compute a proper matrix-matrix product:
[9]:
nd.dot(x, y.T)
[9]:
[[1.4273899 3.219899 ]
[1.4273899 3.219899 ]]
<NDArray 2x2 @cpu(0)>
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,)
.
[10]:
y[1,2]
[10]:
[0.71589124]
<NDArray 1 @cpu(0)>
Read the second and third columns from y
.
[11]:
y[:,1:3]
[11]:
[[0.18568921 0.43037868]
[0.20552671 0.71589124]]
<NDArray 2x2 @cpu(0)>
and writing to a specific element
[12]:
y[:,1:3] = 2
y
[12]:
[[0.09762704 2. 2. ]
[0.6885315 2. 2. ]]
<NDArray 2x3 @cpu(0)>
Multi-dimensional slicing is also supported.
[13]:
y[1:2,0:2] = 4
y
[13]:
[[0.09762704 2. 2. ]
[4. 4. 2. ]]
<NDArray 2x3 @cpu(0)>
Converting between MXNet NDArray and NumPy¶
Converting MXNet NDArrays to and from NumPy is easy. The converted arrays do not share memory.
[14]:
a = x.asnumpy()
(type(a), a)
[14]:
(numpy.ndarray, array([[2., 2., 2.],
[2., 2., 2.]], dtype=float32))
[15]:
nd.array(a)
[15]:
[[2. 2. 2.]
[2. 2. 2.]]
<NDArray 2x3 @cpu(0)>