科学计算之numpy学习

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])
    1. 从普通的python列表或元组来创建数组
    2. 在创建时,可以通过 dtype 指定元素的数据类型,例:np.array([[1,2], [3,4]], dtype=complex)
    3. 其他的创建方式都可以通过 dtype 关键字来指定
  • np.arange(15).reshape(3,5)
    1. 创建0~14 共15个数的一维数组,在reshape的作用下变为二维数组(3 X 5)
    2. 格式:np.arange(low,hight,step)
  • zeros函数创建初始值为0的数组
    1. np.zeros((3,4))
  • ones创建初始值为1的数组
    1. np.ones((3,4))
  • empty创建未初始化的随机数组
    1. np.empty((2,5))
  • linspace
    1. 按预定步长来创建数组
    2. np.linspace(0, 2, 9)     从 [0~2] 生成9个数
  • 随机数组
    1. numpy.random.rand()     创建指定大小的随机数组,取值范围[0,1)
    2. numpy.random.randn()     创建指定大小的数组,取值范围为标准正态分布
    3. numpy.random.randint(low, hight, size=(1,2))     创建指定大小的数组,数组数值随机取于[low,high)之间。high为空时则取[0,low)。需要用到size属性指定数组大小。
    4. numpy.random.seed()     生成随机数种子, 让下一次生成的随机数组与随机数种子关联
    5. 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)相同时才有意义。
    1. 当矩阵A的列数(column)等于矩阵B的行数(row)时,A与B可以相乘。
    2. 矩阵C的行数等于矩阵A的行数,C的列数等于B的列数。
    3. 乘积C的第m行第n列的元素等于矩阵A的第m行的元素与矩阵B的第n列对应元素乘积之和。

数组与数组

数组与数组的算术运算其实同数组与向量的运算一样,其中要注意 矩阵乘法 的成立条件。

注意:

  1. 只有 “同型矩阵” 间才能进行算术计算
  2. 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;

参考资料

  1. https://www.jianshu.com/p/abe7515c6c7f

猜你喜欢

转载自blog.csdn.net/tianzong2019/article/details/106713578
今日推荐