"""
2.2 数据操作
"""
"""
2.2.1 创建NDArray
"""
from mxnet import nd
# 用arange函数创建一个行向量
x = nd.arange(12)
print("x:", x)
print("x.shape:", x.shape)
print("x.size:", x.size)
X = x.reshape((3, 4))
print("X:", X)
"""
x.reshape((-1, 4))或x.reshape((3, -1))。
由于x的元素个数是已知的,这里的-1是能够通过元素个数和其他维度的大小推断出来的。
"""
print(nd.zeros((2, 3, 4)))
Y = nd.array([[2, 1, 4, 3], [1, 2, 3, 4], [4, 3, 2, 1]])
print("Y:", Y)
"""
有些情况下,我们需要随机生成NDArray中每个元素的值。
下面我们创建一个形状为(3, 4)的NDArray。
它的每个元素都随机采样于均值为0、标准差为1的正态分布。
"""
print(nd.random.normal(0, 1, shape=(3, 4)))
print("-------------------------------------------------------------")
"""
2.2.2 运算
"""
print("X + Y:", X + Y)
print("X * Y:", X * Y)
print("X / Y:", X / Y)
print("Y.exp():", Y.exp())
print("nd.dot(X, Y.T):", nd.dot(X, Y.T))
print("nd.concat(X, Y, dim=0):", nd.concat(X, Y, dim=0))
print("nd.concat(X, Y, dim=1):", nd.concat(X, Y, dim=1))
"""
使用条件判断式可以得到元素为0或1的新的NDArray。以X == Y为例,
如果X和Y在相同位置的条件判断为真(值相等),那么新的NDArray在相同位置的值为1;反之为0。
"""
print("X == Y:", X == Y)
print("X.sum():", X.sum())
"""
我们可以通过asscalar函数将结果变换为Python中的标量。
下面例子中X的 L2 范数结果同上例一样是单元素NDArray,但最后结果变换成了Python中的标量。
"""
print("X.norm().asscalar():", X.norm().asscalar())
print("-------------------------------------------------------------")
"""
2.2.3 广播机制
"""
"""
前面我看到如何对两个形状相同的NDArray做按元素运算时,
可能会触发广播(broadcasting)机制:先适当复制元素使这两
个NDArray形状相同后再按元素运算。
"""
A = nd.arange(3).reshape((3, 1))
B = nd.arange(2).reshape((1, 2))
print("A:", A)
print("B:", B)
print("A + B:", A + B)
print("-------------------------------------------------------------")
"""
2.2.4 索引
"""
print("X:", X)
"""
指定了NDArray的行索引截取范围[1:3]。
依据左闭右开指定范围的惯例,它截取了矩阵X中行索引为1和2的两行。
"""
print("X[1:3]:", X[1:3])
print("X[1,2]:", X[1, 2])
X[1, 2]=9
print("X:", X)
print("X[1:2, :]:", X[1:2, :])
X[1:2, :] = 12
print("X:", X)
"""
2.2.5 运算的内存开销
"""
before = id(Y)
Y = Y + X
print("id(Y) == before:", id(Y) == before)
Z = Y.zeros_like()# 先通过zeros_like 创建和Y形状相同且元素为0的NDArray,即为Z
before = id(Z)
Z[:] = X + Y
print("id(Z) == before:", id(Z) == before)
"""
实际上,上例中我们还是为X + Y开了临时内存来存储计算结果,在复制到Z对应的内存。
如果想避开这个临时内存开销,我们可以使用运算符全名函数中的out参数。
"""
nd.elemwise_add(X, Y, out=Z)
print("id(Z) == before:", id(Z) == before)
print("-------------------------------------------------------------")
"""
2.2.6 NDArray 和 NumPy相互变换
"""
import numpy as np
P = np.ones((2,3))
print("P:", P)
D = nd.array(P)
print("D:", D)
# 再将NDArray实例变换成NumPy实例。
print("D.asnumpy:", D.asnumpy())
print("-------------------------------------------------------------")
"""
2.2.8 练习
"""
print("X:", X)
print("Y:", Y)
print("X < Y:", X < Y)
print("X > Y:", X > Y)
if __name__ == '__main__':
pass
-1的一个小作用:
import numpy as np
“”"
新数组的shape属性应该要与原来数组的一致,
即新数组元素数量与原数组元素数量要相等。一个参数为-1时,
那么reshape函数会根据另一个参数的维度计算出数组的另外一个shape属性值。
“”"
z = np.array([[1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12], [13, 14, 15, 16]])
print(“z:”, z)
print(“z.shape:”, z.shape)
print(z.reshape(-1))
print(z.reshape(-1, 1))
#我们不知道z的shape属性是多少,
#但是想让z变成只有一列,行数不知道多少,
#通过z.reshape(-1,1)
,Numpy自动计算出有16行,
#新的数组shape属性为(16, 1),与原来的(4, 4)配套。
print(z.reshape(2,-1))
print(“z.reshape((-1)):”, z.reshape((-1)))