numpy对每一个学python的人都是需要掌握的内容,也有人说“不懂numpy,不要说自己会python”,可见numpy的重要性。我以前也学过numpy,一旦长时间不用,又总会忘记,特开此篇,以记录我所掌握的numpy知识点,公式此文,也可让使用到的同道,可以方便的检索所需要的内容。
必备知识
开篇之前,先来介绍下学numpy之前,需要先了解如下概念:标量,向量,矩阵与张量。
1、标量
一个标量就是一个单独的数,一般用小写的的变量名称表示。
2、向量
一个向量就是一列数,这些数是有序排列的。用次序中的索引,我们可以确定每个单独的数。通常会赋予向量粗体的小写名称。当我们需要明确表示向量中的元素时,我们会将元素排列成一个方括号包围的纵柱:
当然我们也可以把向量看作空间中的点,每个元素是不同的坐标轴上的坐标。
3、矩阵
矩阵是二维数组,其中的每一个元素被两个索引而非一个所确定。我们通常会赋予矩阵粗体的大写变量名称,比如A。 如果一个实数矩阵高度为m,宽度为n,那么我们说
矩阵这东西在机器学习中就不要太重要了!实际上,如果我们现在有N个用户的数据,每条数据含有M个特征,那其实它对应的就是一个NM的矩阵呀;再比如,一张图由1616的像素点组成,那这就是一个16*16的矩阵了。现在才发现,我们大一学的矩阵原理原来这么的有用!要是当时老师讲课的时候先普及一下,也不至于很多同学学矩阵的时候觉得莫名其妙了。
4、张量
几何代数中定义的张量是基于向量和矩阵的推广,通俗一点理解的话,超过两维的数组都叫做张量。我们可以将标量视为零阶张量,矢量视为一阶张量,那么矩阵就是二阶张量。 例如,可以将任意一张彩色图片表示成一个三阶张量,三个维度分别是图片的高度、宽度和色彩数据。
对于一张图来说,一般视为二阶矩阵,矩阵元素为像素,像素的表示可为:ARGB,可用数组表示。也可以说是矢量。
numpy简介
NumPy包的核心是 ndarray 对象。numpy的数组类型是ndarray, 与标准python库的数组不太一样,它包含的元素必须是相同类型的。
Numpy中,维度被称作axes, 维度数被称作rank。
ndarray的常见属性如下:
- ndarray.ndim 数组的轴数(即rank)
- ndarray.shape 数组的维度,返回的是一个元组,元组的长度值刚好是ndim
- ndarray.size 数组元素的个数
- ndarray.dtype 数组元素的类型
- ndarray.itemsize 数组元素的字节大小
- ndarray.data 数组包含的实际数据(一般情况下不会用到这个属性,都是通过索引来访问元素)
创建数组
数组的创建方法有很多种,这里依次罗列
- np.array([2,3,4])
- 从普通的python列表或元组来创建数组
- 在创建时,可以通过 dtype 指定元素的数据类型,例:np.array([[1,2], [3,4]], dtype=complex)
- 其他的创建方式都可以通过 dtype 关键字来指定
- np.arange(15).reshape(3,5)
- 创建0~14 共15个数的一维数组,在reshape的作用下变为二维数组(3 X 5)
- 格式:np.arange(low,hight,step)
- zeros函数创建初始值为0的数组
- np.zeros((3,4))
- ones创建初始值为1的数组
- np.ones((3,4))
- empty创建未初始化的随机数组
- np.empty((2,5))
- linspace
- 按预定步长来创建数组
- np.linspace(0, 2, 9) 从 [0~2] 生成9个数
- 随机数组
- numpy.random.rand() 创建指定大小的随机数组,取值范围[0,1)
- numpy.random.randn() 创建指定大小的数组,取值范围为标准正态分布
- numpy.random.randint(low, hight, size=(1,2)) 创建指定大小的数组,数组数值随机取于[low,high)之间。high为空时则取[0,low)。需要用到size属性指定数组大小。
- numpy.random.seed() 生成随机数种子, 让下一次生成的随机数组与随机数种子关联
- numpy.random.shuffle(数组) 将数组中的元素打乱。
随机数组示例
# 创建2行2列取值范围为[0,1)的数组
arr = np.random.rand(2,2)
# 创建一维数组,元素个数为10,取值范围为[0,1)
arr1 = np.random.rand(10)
# 创建2行3列,取值范围为标准正态分布的数组
arr2 = np.random.randn(2,3)
# 创建3维数组 2x2x3,其元素为[1~20]之间的随机数
arr3 = np.random.randint(1,20,size=(2,2,3))
# 将数组arr1中的元素顺序打乱
arr4 = np.random.shuffle(arr1)
# 生成一个随机数种子为seed1,参数可自己随意设定
np.random.seed(seed1)
算术运算
数组与标量
数组与标量的算术运算,其实就是每个都元素与这个标量的算术运算。可用的运算:加、减、乘、除、取余
import numpy as np
a = np.arange(0,5)
a
Out[3]: array([0, 1, 2, 3, 4])
a+2
Out[4]: array([2, 3, 4, 5, 6])
a-2
Out[5]: array([-2, -1, 0, 1, 2])
a*2
Out[6]: array([0, 2, 4, 6, 8])
a/2
Out[7]: array([0. , 0.5, 1. , 1.5, 2. ])
np.mod(a,2)
Out[8]: array([0, 1, 0, 1, 0], dtype=int32)
a**2
Out[9]: array([ 0, 1, 4, 9, 16], dtype=int32)
数组与向量
列相同
数组与 列相同 的向量运算
- “ *” 返回的是每个元素相乘的结果,要实现矩阵乘法,需要使用dot函数
import numpy as np
a = np.arange(12).reshape(4,3)
a
Out[3]:
array([[ 0, 1, 2],
[ 3, 4, 5],
[ 6, 7, 8],
[ 9, 10, 11]])
b = np.array([2,2,2])
b
Out[5]: array([2, 2, 2])
a + b
Out[6]:
array([[ 2, 3, 4],
[ 5, 6, 7],
[ 8, 9, 10],
[11, 12, 13]])
a - b
Out[7]:
array([[-2, -1, 0],
[ 1, 2, 3],
[ 4, 5, 6],
[ 7, 8, 9]])
a * b
Out[8]:
array([[ 0, 2, 4],
[ 6, 8, 10],
[12, 14, 16],
[18, 20, 22]])
a / b
Out[9]:
array([[0. , 0.5, 1. ],
[1.5, 2. , 2.5],
[3. , 3.5, 4. ],
[4.5, 5. , 5.5]])
np.mod(a,b)
Out[10]:
array([[0, 1, 0],
[1, 0, 1],
[0, 1, 0],
[1, 0, 1]], dtype=int32)
a.dot(b)
Out[11]: array([ 6, 24, 42, 60])
行相同
数组与 行相同 的向量运算,不支持矩阵乘法,只支持元素算术运算
c = np.array([3,3,3,3]).reshape(4,1)
c
Out[14]:
array([[3],
[3],
[3],
[3]])
a + c
Out[15]:
array([[ 3, 4, 5],
[ 6, 7, 8],
[ 9, 10, 11],
[12, 13, 14]])
a - c
Out[16]:
array([[-3, -2, -1],
[ 0, 1, 2],
[ 3, 4, 5],
[ 6, 7, 8]])
a * c
Out[17]:
array([[ 0, 3, 6],
[ 9, 12, 15],
[18, 21, 24],
[27, 30, 33]])
a / c
Out[18]:
array([[0. , 0.33333333, 0.66666667],
[1. , 1.33333333, 1.66666667],
[2. , 2.33333333, 2.66666667],
[3. , 3.33333333, 3.66666667]])
np.mod(a,c)
Out[19]:
array([[0, 1, 2],
[0, 1, 2],
[0, 1, 2],
[0, 1, 2]], dtype=int32)
综上演示,数组与向量的运算其实就是,数组与数组的运算,其中用到了 广播 的概念,先把“行向量” 或 “列向量” 扩展成了一个同型矩阵,再与原矩阵运算。
在这里普及下矩阵的几个概念:
- “同阶矩阵" 概念首先针对的是方阵(方阵的行数 [等于列数] 称为它的阶数),所以“同阶矩阵是指阶数相同的矩阵”。
- “同型矩阵” 只是要求行数和列数分别相等,不要求是方阵。而“同阶矩阵”必须要求行数和列数都要相同。
- “矩阵乘法” 只有在第一个矩阵的列数(column)和第二个矩阵的行数(row)相同时才有意义。
- 当矩阵A的列数(column)等于矩阵B的行数(row)时,A与B可以相乘。
- 矩阵C的行数等于矩阵A的行数,C的列数等于B的列数。
- 乘积C的第m行第n列的元素等于矩阵A的第m行的元素与矩阵B的第n列对应元素乘积之和。
数组与数组
数组与数组的算术运算其实同数组与向量的运算一样,其中要注意 矩阵乘法 的成立条件。
注意:
- 只有 “同型矩阵” 间才能进行算术计算
- numpy的广播只对 “行向量” 和 “列向量” 有效
import numpy as np
a = np.arange(12).reshape(4,3)
a
Out[3]:
array([[ 0, 1, 2],
[ 3, 4, 5],
[ 6, 7, 8],
[ 9, 10, 11]])
b = np.zeros((4,3))
b
Out[5]:
array([[0., 0., 0.],
[0., 0., 0.],
[0., 0., 0.],
[0., 0., 0.]])
b.fill(3)
b
Out[7]:
array([[3., 3., 3.],
[3., 3., 3.],
[3., 3., 3.],
[3., 3., 3.]])
a + b
Out[8]:
array([[ 3., 4., 5.],
[ 6., 7., 8.],
[ 9., 10., 11.],
[12., 13., 14.]])
a - b
Out[9]:
array([[-3., -2., -1.],
[ 0., 1., 2.],
[ 3., 4., 5.],
[ 6., 7., 8.]])
a * b
Out[10]:
array([[ 0., 3., 6.],
[ 9., 12., 15.],
[18., 21., 24.],
[27., 30., 33.]])
a / b
Out[11]:
array([[0. , 0.33333333, 0.66666667],
[1. , 1.33333333, 1.66666667],
[2. , 2.33333333, 2.66666667],
[3. , 3.33333333, 3.66666667]])
np.mod(a,b)
Out[12]:
array([[0., 1., 2.],
[0., 1., 2.],
[0., 1., 2.],
[0., 1., 2.]])
通用函数
Numpy提供了很多常见的数学上的运算,如sin, cos, exp。使用到时,请大家自行搜索……
广播
要能满足广播,必须符合下面两条规则:
- 广播之后,输出数组的shape是输入数组shape的各个轴上的最大值,然后沿着较大shape属性的方向复制延伸;
- 要进行广播机制,要么两个数组的shape属性一样,要么其中有一个数组的shape属性必须有一个等于1;
参考资料
- https://www.jianshu.com/p/abe7515c6c7f