欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

开启 numpy 的学习之旅

程序员文章站 2022-03-29 16:49:01
...

开启 numpy 的学习之旅

numpy 是 python 的一个矩阵运算包,学习它的目的是做专业设计的仿真,起因是讨厌 Matlab 的封闭性,虽然很方便,可**,但是不可控(老美打压华为得到的启示),使用 python 是为了替换掉 matlab 。
矩阵运算使用 python 的原生数据类型 list 或者是官方提供的 array 模块都可以实现,但是在运算速度上都不及 numpy,这是 numpy 的优势所在。
numpy 提供 2 个基本对象,ndarray 和 ufunc 。ndarray 多维数组,当然我习惯称之为矩阵;ufunc 则是能够对矩阵进行处理的函数。

一、首先,学会创建一维矩阵

(一)第一类创建方法–转换

import numpy as np # 调入 numpy 包

# 创建数组的第一种方式,使用 array 方法将 python 序列转换成矩阵
l_a = [1,2,3,4] # 列表
t_a = (1,2,3,4) # 元组
str_a = '1,2,3,4' # 字符串
set_a = {1,2,3,4} # 集合

array_a = np.array(l_a)
print('看一下列表到矩阵的转换:',end="")
print(type(l_a),l_a,'\t',type(array_a),array_a)

array_b = np.array(t_a)
print('看一下元组到矩阵的转换:',end="")
print(type(t_a),t_a,'\t',type(array_b),array_b)

array_c = np.array(str_a)
print('看一下字符串到矩阵的转换:',end="")
print(type(str_a),str_a,'\t',type(array_c),array_c)
# print(array_c[2])

array_d = np.array(set_a)
print('看一下集合到矩阵的转换:',end="")
print(type(set_a),set_a,'\t',type(array_d),array_d)
# print(array_d[0])
看一下列表到矩阵的转换:<class 'list'> [1, 2, 3, 4] 	 <class 'numpy.ndarray'> [1 2 3 4]
看一下元组到矩阵的转换:<class 'tuple'> (1, 2, 3, 4) 	 <class 'numpy.ndarray'> [1 2 3 4]
看一下字符串到矩阵的转换:<class 'str'> 1,2,3,4 	 <class 'numpy.ndarray'> 1,2,3,4
看一下集合到矩阵的转换:<class 'set'> {1, 2, 3, 4} 	 <class 'numpy.ndarray'> {1, 2, 3, 4}


运行上述一段代码,可以看出转换 list, tuple 还是ok的,碰到 str,set 没办法转换成理想结果了,得到的是一个 0 维数组,可以删除 print 注释,看一下运行结果。

(二)第二类创建方法–快捷函数

import numpy as np
# 如果我们把上面一类创建矩阵的方法总结为转换的话
# 那么接下来看一些更快捷的矩阵创建方式,毕竟创建之前还要定义一下数据还是挺累的。

# arange(), 懂原生的 range() ,这个就很 easy 啦.
# numpy 的 arange
array_a = np.arange(2,12,2) 
# 第一个参数为起始点,第二个参数嘛就是终点咯(不包含的那种),第三个参数自然就是步进啦

print('来看一下numpy定义的arange:',end="")
print(type(array_a),array_a)
来看一下numpy定义的arange:<class 'numpy.ndarray'> [ 2  4  6  8 10]
import numpy as np

# 上面呢,我们是 arange 函数来创建的等差数列
# 下面我们来一下另外一种方式,函数 linsapce
array_a = np.linspace(2,12,5)
# 前两个参数与 arange 一样,不同的是,第三个参数 linspace 指定的是元素个数,
# 除此之外,还有一个不同点,linspace 包含终点
# 那么不包含终点呢?
array_b = np.linspace(2,12,5,endpoint = False)

print('来看一下numpy定义的linspace(包含终点):',end="")
print(type(array_a),array_a)

print('来看一下numpy定义的linspace(不包含终点):',end="")
print(type(array_b),array_b)
来看一下numpy定义的linspace(包含终点):<class 'numpy.ndarray'> [ 2.   4.5  7.   9.5 12. ]
来看一下numpy定义的linspace(不包含终点):<class 'numpy.ndarray'> [ 2.  4.  6.  8. 10.]


numpy 里的 arange 和 linsapce 创建的都是等差数列,那么等比呢? 使用函数 logspace
import numpy as np

array_a = np.logspace(0,4,5)
# 默认以 10 为底数
# 第一个参数是起始点的指数,第二个参数是终点的指数,第三个参数是元素的个数

array_b = np.logspace(0,4,5,base=2)
# 切换一下底数,以 2 为底

array_c = np.logspace(0,4,5,endpoint = False)
# 不包含终点

# 对比一下,那么不用 logspace 怎么写呢?
array_d = np.array([ 10**i for i in range(0,5)])

print('来看一下numpy定义的logspace(包含终点):',end="")
print(type(array_a),array_a)
print('来看一下numpy定义的logspace,以2为底:',end="")
print(type(array_b),array_b)
print('来看一下numpy定义的logspace(不包含终点):',end="")
print(type(array_c),array_c)
print('来看一下原生创建等比数列:',end="")
print(type(array_d),array_d)
来看一下numpy定义的logspace(包含终点):<class 'numpy.ndarray'> [1.e+00 1.e+01 1.e+02 1.e+03 1.e+04]
来看一下numpy定义的logspace,以2为底:<class 'numpy.ndarray'> [ 1.  2.  4.  8. 16.]
来看一下numpy定义的logspace(不包含终点):<class 'numpy.ndarray'> [1.00000000e+00 6.30957344e+00 3.98107171e+01 2.51188643e+02
 1.58489319e+03]
来看一下原生创建等比数列:<class 'numpy.ndarray'> [    1    10   100  1000 10000]

二、进军多维矩阵

在开始聊多多维矩阵之前,让我们先来了解几个概念。数组的维度信息,还有矩阵的数据类型。

需要了解的一些知识背景

import numpy as np

# 利用上面我们了解的一些知识,来创建一个一维矩阵试试。
array_a = np.arange(10)
# 来查询一下矩阵的维度
nd_a = array_a.shape
#来看一下矩阵的数据类型
tp_a = array_a.dtype

print('看一下矩阵的一些信息:')
print('矩阵元素:',array_a,'\t','矩阵类型:',type(array_a),'\t','矩阵维度:',nd_a,'\t','矩阵数据类型:',tp_a)
看一下矩阵的一些信息:
矩阵元素: [0 1 2 3 4 5 6 7 8 9] 	 矩阵类型: <class 'numpy.ndarray'> 	 矩阵维度: (10,) 	 矩阵数据类型: int32


先看看维度信息,因为是一维矩阵,矩阵的维度信息给出元素的个数,注意这里是一个元组。

再看看数据类型吧,学习过 C 语言的小伙伴们对 int32 应该很熟悉,32位有符号整型。在学习的过程中,我们不断在扩充对数据类型的认识,从整数到分数,从实数到复数。到了计算机的世界里,数据类型又跟存储位数挂钩...因此衍生出很多数据类型,来让我们看看都有哪些?
import numpy as np

tp_num = set(np.typeDict.values())

print('numpy 支持的数据类型:')
print(tp_num)
numpy 支持的数据类型:
{<class 'numpy.int16'>, <class 'numpy.intc'>, <class 'numpy.bool_'>, <class 'numpy.str_'>, <class 'numpy.bytes_'>, <class 'numpy.clongdouble'>, <class 'numpy.timedelta64'>, <class 'numpy.complex128'>, <class 'numpy.uintc'>, <class 'numpy.void'>, <class 'numpy.uint32'>, <class 'numpy.uint64'>, <class 'numpy.int8'>, <class 'numpy.uint8'>, <class 'numpy.float64'>, <class 'numpy.float32'>, <class 'numpy.datetime64'>, <class 'numpy.object_'>, <class 'numpy.complex64'>, <class 'numpy.uint16'>, <class 'numpy.float16'>, <class 'numpy.int32'>, <class 'numpy.int64'>, <class 'numpy.longdouble'>}

(一)第一类创建方法–转换

import numpy as np

array_1d = np.array([0,1,2,3,4,5],dtype = np.int16) # 创建 1x6 的一维矩阵,设置数据类型为 16 位有符号整型
array_2d = np.array([[1,2,3],[4,5,6]],dtype = np.float32) # 创建 2x3 的二维矩阵,设置数据类型为 32 位浮点型
array_3d = np.array([[[1,2],[3,4]],[[5,6],[7,8]]],dtype = np.complex64) # 创建 2x2x2 的三维矩阵,设置数据类型为 64 位复数型

print('一维矩阵:',array_1d,'\t',array_1d.shape)
print('二维矩阵:',array_2d,'\t',array_2d.shape)
print('三维矩阵:',array_3d,'\t',array_3d.shape)
一维矩阵: [0 1 2 3 4 5] 	 (6,)
二维矩阵: [[1. 2. 3.]
 [4. 5. 6.]] 	 (2, 3)
三维矩阵: [[[1.+0.j 2.+0.j]
  [3.+0.j 4.+0.j]]

 [[5.+0.j 6.+0.j]
  [7.+0.j 8.+0.j]]] 	 (2, 2, 2)

(二)第二类创建方法–变形

import numpy as np

array_1d = np.array([0,1,2,3,4,5],dtype = np.int16) # 创建 1x6 的一维矩阵,设置数据类型为 16 位有符号整型
array_2d = np.array([[1,2,3],[4,5,6]],dtype = np.float32) # 创建 2x3 的二维矩阵,设置数据类型为 32 位浮点型
array_3d = np.array([[[1,2],[3,4]],[[5,6],[7,8]]],dtype = np.complex64) # 创建 2x2x2 的三维矩阵,设置数据类型为 64 位复数型

a_1d_trans = array_1d.reshape((3,2)) # 将 1x6 的一维矩阵转换成 3x2 的矩阵
a_2d_trans = array_2d.reshape((6,)) # 将 2x3 的矩阵转换成 1x6 的矩阵
a_3d_trans = array_3d.reshape((2,4)) # 将 2x2x2 的三维矩阵转换成 2x4 的二维矩阵

print('一维矩阵:',array_1d,'\t',array_1d.shape)
print('二维矩阵:',array_2d,'\t',array_2d.shape)
print('三维矩阵:',array_3d,'\t',array_3d.shape)

print('\n创建的数据与上述数据相同,来看一下变形之后的数据:\n')

print('上述一维矩阵变形后:',a_1d_trans,a_1d_trans.shape)
print('上述二维矩阵变形后:',a_2d_trans,a_2d_trans.shape)
print('上述三维矩阵变形后:',a_3d_trans,a_3d_trans.shape)
一维矩阵: [0 1 2 3 4 5] 	 (6,)
二维矩阵: [[1. 2. 3.]
 [4. 5. 6.]] 	 (2, 3)
三维矩阵: [[[1.+0.j 2.+0.j]
  [3.+0.j 4.+0.j]]

 [[5.+0.j 6.+0.j]
  [7.+0.j 8.+0.j]]] 	 (2, 2, 2)

创建的数据与上述数据相同,来看一下变形之后的数据:

上述一维矩阵变形后: [[0 1]
 [2 3]
 [4 5]] (3, 2)
上述二维矩阵变形后: [1. 2. 3. 4. 5. 6.] (6,)
上述三维矩阵变形后: [[1.+0.j 2.+0.j 3.+0.j 4.+0.j]
 [5.+0.j 6.+0.j 7.+0.j 8.+0.j]] (2, 4)

(三)第三类创建方法–快捷函数

numpy 中提供了一些快速创建多维矩阵的函数,zeros, ones, empty.
import numpy as np

# 给定上述函数指定的维度信息,就会创建出相应的数据。
# 其功能顾名思义,zerros 初始化置零, ones 初始化置一,empty 只声明不初始化,内容随机。

a = np.zeros((8,))
b = np.ones((4,4))
c = np.empty((2,8))

print('矩阵a:')
print(a)
print('矩阵b:')
print(b)
print('矩阵c:')
print(c)

# 接下来介绍一些复制函数
# zeros_like, ones_like, empty_like
# 根据给定矩阵的维度信息,复刻出相同维的矩阵,初始化置零,置一,不初始化。
# 仅以 zeros_like 为例

d = np.arange(10)
e = np.zeros_like(d)
print('\n展示复制函数:\n')
print('原始矩阵:',d,d.shape,'\t','复刻置零矩阵:',e,e.shape)

矩阵a:
[0. 0. 0. 0. 0. 0. 0. 0.]
矩阵b:
[[1. 1. 1. 1.]
 [1. 1. 1. 1.]
 [1. 1. 1. 1.]
 [1. 1. 1. 1.]]
矩阵c:
[[1. 1. 1. 1. 1. 1. 1. 1.]
 [1. 1. 1. 1. 1. 1. 1. 1.]]

展示复制函数:

原始矩阵: [0 1 2 3 4 5 6 7 8 9] (10,) 	 复刻置零矩阵: [0 0 0 0 0 0 0 0 0 0] (10,)