NumPy-矩阵部分
NumPy-矩阵部分
[TOC]
NumPy 简介
NumPy是一个在python里面用的库,不过它是c编写的。
安装NumPy
pip install numpy
导入 NumPy
在导入 NumPy 库时,大多数情况下(包括这里)你会看到的一个约定,是将其命名为 np
import numpy as np
数据类型和形状
NumPy 中处理数字的最常见方式是通过 ndarray
对象。它们与 Python 列表相似,但是可以有任意数量的维度。而且,ndarray
支持快速的数学运算。
NumPy里面的数据类型比Python的多。python只有int
、float。在NumPy中除了 Python 的
int,你可以使用
uint8、
int8、
uint16、
int16` 等类型。ndarray中的每一项必须具有相同的类型,和c类似。
创建包含一个标量的 NumPy 数组:
s=np.array(5)
可以通过检查数组的 shape
属性来查看数组的形状。
s.shape
它会打印出结果,即一对空括号 ()
。这表示它的维度为零。
即使标量位于数组中,你仍然可以像正常标量一样使用它们。你可以键入:
x = s + 3
x
现在将等于 8
。如果你检查 x
的类型,会发现它可能是 numpy.int64
,因为它在使用 NumPy 类型,而不是 Python 类型。
创建一个向量:
v=np.array([1,2,3])
检查向量的 shape
属性,它将返回表示向量的一维长度的单个数字。在上面的示例中,v.shape
会返回 (3,)
。
现在有了数字,你可以看到 shape 是一个元组,其中包含每个 ndarray
的维度的大小。对于标量,它只是一个空的元组,但是向量有一个维度,所以元组包含一个数字和一个逗号。(Python 不能将 (3)
理解为具有一个项的元组,所以它需要逗号。
你可以使用索引访问向量中的元素,如下所示:
x = v[1]
现在 x
等于 2
。
NumPy 还支持高级索引技术。例如,要访问第二个元素及其后面的项,你可以这样写:
v[1:]
然后它会返回数组 [2, 3]
。
创建矩阵
m=np.array([[1,2,3],[4,5,6],[7,8,9]])
创建了一个包含数字 1 到 9 的 3×3 矩阵。
它的 shape
属性将返回元组 (3, 3)
所以要在上面的矩阵中找到数字 6
,你可以访问 m[1][2]
。
张量
张量可以有更多的维度。
如,要创建一个 3x3x2x1 的张量
t = np.array([[[[1],[2]],[[3],[4]],[[5],[6]]],[[[7],[8]],[[9],[10]],[[11],[12]]],[[[13],[14]],[[15],[16]],[[17],[17]]]])
t[2][1][1][0]
将返回 16
。
更改形状
更改数据的形状,而不实际更改其内容。例如,你可能有一个一维的向量,但是需要一个二维的矩阵。实现它的方式有两种。
假设你有以下向量:
v = np.array([1,2,3,4])
调用 v.shape
会返回 (4,)
。但如果你想要一个 1×4 矩阵呢?你可以使用 reshape
函数,就像这样:
x = v.reshape(1,4)
调用 x.shape
会返回 (1,4)
。如果你想要一个 4×1 矩阵,可以这样做:
x = v.reshape(4,1)
reshape
函数不只是添加大小为 1 的维度。
关于更改 NumPy 数组的形状还有一点:如果你看到经验丰富的 NumPy 使用者的代码,经常会看到他们使用一种特殊的切片语法,而不是调用 reshape
。使用该语法,前面的两个示例会是这样的:
x = v[None, :]
或者
x = v[:, None]
NumPy里面的矩阵运算
values = [1,2,3,4,5]
values = np.array(values) + 5
# 现在 values 是包含 [6,7,8,9,10] 的一个 ndarray
NumPy 实际上有用于加法、乘法等运算的函数。
以下两行是等价的:
x = np.multiply(some_array, 5)
x = some_array * 5
矩阵归零:
m *= 0
# 现在 m 中的每个元素都是 0,无论它有多少维度
矩阵的平方值:
x = m * m
(或者如果你要将值赋值回 m
,则是 m *= m
)
a = np.array([[1,3],[5,7]])
a
# 显示以下结果:
# array([[1, 3],
# [5, 7]])
b = np.array([[2,4],[6,8]])
b
# 显示以下结果:
# array([[2, 4],
# [6, 8]])
a + b
# 显示以下结果:
# array([[ 3, 7],
# [11, 15]])
不兼容的形状,会收到一个错误:
a = np.array([[1,3],[5,7]])
a
# 显示以下结果:
# array([[1, 3],
# [5, 7]])
c = np.array([[2,3,6],[4,5,9],[1,8,7]])
c
# 显示以下结果:
# array([[2, 3, 6],
# [4, 5, 9],
# [1, 8, 7]])
a.shape
# 显示以下结果:
# (2, 2)
c.shape
# 显示以下结果:
# (3, 3)
a + c
# 显示以下结果:
# ValueError: operands could not be broadcast together with shapes (2,2) (3,3)
要获得矩阵乘积,可以使用 NumPy 的 matmul
函数。
如果你有兼容的形状,那就像这样简单:
a = np.array([[1,2,3,4],[5,6,7,8]])
a
# 显示以下结果:
# array([[1, 2, 3, 4],
# [5, 6, 7, 8]])
a.shape
# 显示以下结果:
# (2, 4)
b = np.array([[1,2,3],[4,5,6],[7,8,9],[10,11,12]])
b
# 显示以下结果:
# array([[ 1, 2, 3],
# [ 4, 5, 6],
# [ 7, 8, 9],
# [10, 11, 12]])
b.shape
# 显示以下结果:
# (4, 3)
c = np.matmul(a, b)
c
# 显示以下结果:
# array([[ 70, 80, 90],
# [158, 184, 210]])
c.shape
# 显示以下结果:
# (2, 3)
如果你的矩阵具有不兼容的形状,则会出现以下错误:
np.matmul(b, a)
# 显示以下错误:
# ValueError: shapes (4,3) and (2,4) not aligned: 3 (dim 1) != 2 (dim 0)
*** tf.multiply是点乘,tf.matmul是矩阵乘法 ***