MXNet数据操作基础学习(NDArray)
NDArray 程序包 (mxnet.ndarray) 包含类似于 numpy.ndarray 的张量计算包。两者的语法很相近,但NDArray能够提供更多的功能,如CPU和GPU的异步计算和自动求导功能。(本文代码来自《动手学深度学习》(李沐))
一、创建
from mxnet import nd #导入mxnet为nd
x = nd.arange(12);x # 利用arange函数创建一个0-11的行向量
OUT1:
[ 0. 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11.]
<NDArray 12 @cpu(0)>
print(x.shape) #查看x的形状
print(x.size) #查看x中元素的总数
OUT1:
(12,)
OUT2:
12
X = x.reshape(3,4);X #利用reshape函数将x向量转化成三行四列的矩阵(二维张量)X
x.reshape(-1,3) #利用reshape的函数将x转化为三列,其中行数不确定的张量(元素总数已知,行数可以推断出,用-1表示即可)
OUT1:
[[ 0. 1. 2. 3.]
[ 4. 5. 6. 7.]
[ 8. 9. 10. 11.]]
<NDArray 3x4 @cpu(0)>
OUT2:
[[ 0. 1. 2.]
[ 3. 4. 5.]
[ 6. 7. 8.]
[ 9. 10. 11.]]
<NDArray 4x3 @cpu(0)>
nd.zeros((2,3,4)) #创建一个各元素都为零,形状为(2,3,4)的张量
nd.ones((3,4)) #创建一个各元素为1形状为(3,4)的张量
OUT1:
[[[0. 0. 0. 0.]
[0. 0. 0. 0.]
[0. 0. 0. 0.]]
[[0. 0. 0. 0.]
[0. 0. 0. 0.]
[0. 0. 0. 0.]]]
<NDArray 2x3x4 @cpu(0)>
OUT2:
[[1. 1. 1. 1.]
[1. 1. 1. 1.]
[1. 1. 1. 1.]]
<NDArray 3x4 @cpu(0)>
Y = nd.array([[2,1,4,3,],[1,2,3,4],[4,3,2,1]]);Y #通过列表指定需要创建的NDArray中每个元素的值
OUT1:
[[2. 1. 4. 3.]
[1. 2. 3. 4.]
[4. 3. 2. 1.]]
<NDArray 3x4 @cpu(0)>
nd.random.normal(0,1,shape = (3,4)) #创建一个形状为(3,4)的NDArray,它的值服从均值为0,标准差为1的随机正态分布
OUT1:
[[ 1.1630785 0.4838046 0.29956347 0.15302546]
[-1.1688148 1.558071 -0.5459446 -2.3556297 ]
[ 0.54144025 2.6785064 1.2546344 -0.54877406]]
<NDArray 3x4 @cpu(0)>
二、运算
print(X) #X矩阵
print(Y) #Y矩阵
X+Y #NDArray支持大量的运算符, X+Y两个矩阵按照元素相加
OUT1:
[[ 0. 1. 2. 3.]
[ 4. 5. 6. 7.]
[ 8. 9. 10. 11.]]
<NDArray 3x4 @cpu(0)>
OUT2:
[[2. 1. 4. 3.]
[1. 2. 3. 4.]
[4. 3. 2. 1.]]
<NDArray 3x4 @cpu(0)>
OUT3:
[[ 2. 2. 6. 6.]
[ 5. 7. 9. 11.]
[12. 12. 12. 12.]]
<NDArray 3x4 @cpu(0)>
X/Y #按照元素位置做除法
OUT1:
[[ 0. 1. 0.5 1. ]
[ 4. 2.5 2. 1.75]
[ 2. 3. 5. 11. ]]
<NDArray 3x4 @cpu(0)>
Y.exp() #对Y矩阵按照元素做指数运算
OUT1:
[[ 7.389056 2.7182817 54.59815 20.085537 ]
[ 2.7182817 7.389056 20.085537 54.59815 ]
[54.59815 20.085537 7.389056 2.7182817]]
<NDArray 3x4 @cpu(0)>
print(nd.dot(X,Y.T)) #可以用dot做矩阵乘法运算,Y.T表示矩阵转置
OUT1:
[[ 18. 20. 10.]
[ 58. 60. 50.]
[ 98. 100. 90.]]
<NDArray 3x3 @cpu(0)>
nd.concat (X,Y,dim = 0) #矩阵按行连结
nd.concat (X,Y,dim = 1) #矩阵按列连结
OUT1:
[[ 0. 1. 2. 3.]
[ 4. 5. 6. 7.]
[ 8. 9. 10. 11.]
[ 2. 1. 4. 3.]
[ 1. 2. 3. 4.]
[ 4. 3. 2. 1.]]
<NDArray 6x4 @cpu(0)>
OUT2:
[[ 0. 1. 2. 3. 2. 1. 4. 3.]
[ 4. 5. 6. 7. 1. 2. 3. 4.]
[ 8. 9. 10. 11. 4. 3. 2. 1.]]
<NDArray 3x8 @cpu(0)>
X==Y #条件判别式,如果X,Y位置上的元素相同,那么新NDArray的相同位置则为1,否则为0
OUT1:
[[0. 1. 0. 1.]
[0. 0. 0. 0.]
[0. 0. 0. 0.]]
<NDArray 3x4 @cpu(0)>
X.sum() #元素求和
OUT1:
[66.]
<NDArray 1 @cpu(0)>
三、广播机制
当对两个形状不同的NDArray进行运算时,可能会触发广播机制:适当复制元素使得两个NDArray形状相同后再按照元素进行运算。
简单来说,广播机制可以这样理解:如果你有一个m*n的矩阵,让它加减乘除一个1*n 的矩阵,它会被复制m次,成为一个m*n的矩阵,然后再逐元素地进行加减乘除操作。同样地对m*1的矩阵成立.
A =nd.arange(3).reshape((3,1)) #构建一个3*1的矩阵,共3个元素
B =nd.arange(2).reshape((1,2))#构建一个1*2的矩阵,共2个元素
print(A)
print(B)
print(A+B) #广播机制,将A中第一列的三个元素复制到第二列,B中第一行的2个元素被复制到第二行和第三行,从而形成两个三行两列的矩阵相加
OUT1:
[[0.]
[1.]
[2.]]
<NDArray 3x1 @cpu(0)>
OUT2:
[[0. 1.]]
<NDArray 1x2 @cpu(0)>
OUT3:
[[0. 1.]
[1. 2.]
[2. 3.]]
<NDArray 3x2 @cpu(0)>
print(X)
X[1:3] #索引,遵循python索引的左闭右开和从0开始原则,索引第2到3行
OUT1:
[[ 0. 1. 2. 3.]
[ 4. 5. 6. 7.]
[ 8. 9. 10. 11.]]
<NDArray 3x4 @cpu(0)>
OUT2:
[[ 4. 5. 6. 7.]
[ 8. 9. 10. 11.]]
<NDArray 2x4 @cpu(0)>
X[1,2] = 9;X #访问第一行第二列的元素,为其重新赋值为9
OUT1:
[[ 0. 1. 2. 3.]
[ 4. 5. 9. 7.]
[ 8. 9. 10. 11.]]
<NDArray 3x4 @cpu(0)>
X[1:2,:] = 12;X #索引第二行所有元素,将其赋值为12
OUT1:
[[ 0. 1. 2. 3.]
[12. 12. 12. 12.]
[ 8. 9. 10. 11.]]
<NDArray 3x4 @cpu(0)>
四、转换
import numpy as np#导入numpy P = np.ones((2,3));P#numpy构建
OUT1:
array([[1., 1., 1.],
[1., 1., 1.]])
D = nd.array(P);D#转换为NDArray
OUT1:
[[1. 1. 1.]
[1. 1. 1.]]
<NDArray 2x3 @cpu(0)>
D.asnumpy()#NDArray转化为numpy
OUT1:
array([[1., 1., 1.],
[1., 1., 1.]], dtype=float32)