- 本文来自《Python数据分析从入门到精通》——明日科技编著
- NumPy为数据分析三剑客之一,主要用于数组计算、矩阵运算和科学计算。对于本章的学习,建议初学者灵活学习,重点掌握数组创建、数组的简单操作和计算即可。
- 为了便于理解,本章运用了大量的示意图,用例简单,力求是您能够轻松地融入NumPy的学习中。通过典型案例,让您充分理解NumPy、应用NumPy。
- 下面让我们揭开NumPy神秘的面纱,开启NumPy之旅。
8.1 初始NumPy
8.1.1 NumPy概述
- NumPy更像是一个魔方,它是Python数组计算、矩阵运算和科学计算的核心库,NumPy这个来源于Numerical和Python两个单词。NumPy提供了一个高性能的数组对象,让我们轻松创建一维数组、二维数组和多维数组,以及大量的函数和方法,帮助我们轻松地进行数组计算,从而广泛地应用于数据分析、机器学习、图像处理和计算机图形学、数学任务等领域当中。
- NumPy的用途是以数组的形式对数据进行操作。机器学习中充斥了大量的数组运算,而NumPy使得这些操作变得简单!由于NumPy是C语言实现的,所以其运算速度非常快。具体功能如下:
- 有一个强大的n维数组对象ndarray。
- 广播功能函数。
- 线性代数、傅里叶变换、随机数生成、图形操作等功能。
- 整合C/C++/Fortran代码的工具。
8.1.2 安装NumPy模块
- 略
8.1.3 数组相关概念
1.一维数组
- 一维数组很简单,基本和Python列表一样,区别在于数组切片针对的是原始数组(这就意味着,如果对数组进行修改,原始数组也会跟着更改)。
2.二维数组
- 二维数组本质是以数组作为数组元素的数组。二维数组包括行和列,类似于表格形状,又称为矩阵。
3.三维数组
- 三维数组是指维数为3的数组结构,也称矩阵列表。三维数组是最常见的多维数组,由于其可以用来描述三维空间中的位置或状态而被广泛使用。
4.轴的概念
- 轴是NumPy里的axis,指定某个axis,就是沿着这个axis做相关操作,其中二维数组中的两个axis的指向如图8.6所示。
-
对于一维数组,情况有点特殊,它不像二维数组从上向下的操作,而是水平的,因此一维数组其axis=0指向如图8.7所示。
8.2 创建数组
8.2.1 创建简单的数组
- NumPy创建简单的数组主要使用array()函数,语法如下:
numpy.array(object,dtype=None,copy=True,order='K',subok=False,ndmin=0)
- object:任何具有数组接口方法的对象。
- dtype:数组类型。
- copy:布尔型,可选参数,默认值为True,则object对象被复制;否则,只有当__array__返回副本,object参数为嵌套序列,或者需要副本满足数据类型和顺序要求时,才会生成副本。
- order:元素在内存中的出现顺序,值为K、A、C、F。如果object参数不是数组,则创建的数组将按行排列(C),如果值为F,则按列排列;如果object参数是一个数组,则C(按行)、A(原顺序)、K(元素在内存中的出现顺序)成立。
- subok:布尔型。如果值为True,则将传递子类;否则返回的数组将强制为基类数组(默认值)。
- ndmin:指定生成数组的最小维数。
1.为数组指定数据类型(02)
- NumPy支持比Python更多种类的数据类型,通过dtype参数可以指定数组的数据类型,程序代码如下:
list = [1, 2, 3] #列表
# 创建浮点型数组
n1 = np.array(list,dtype=np.float_)
#或者
n1= np.array(list,dtype=float)
print(n1)
print(n1.dtype)
print(type(n1[0]))
[1. 2. 3.]
float64
<class 'numpy.float64'>
2.数组的复制(03)
- 当运算和处理数组时,为了不影响到原数组,就需要对原数组进行复制,而对复制后的数组进行修改删除等操作都不会影响到原数组。数组的复制可以通过copy参数实现,程序代码如下:
import numpy as np #导入numpy模块
n1 = np.array([1,2,3]) #创建数组
n2 = np.array(n1,copy=True) #复制数组
n2[0]=3 #修改数组中的第一个元素为3
n2[2]=1 #修改数组中的第三个元素为1
print(n1)
print(n2)
[1 2 3]
[3 2 1]
- 数据n2是数组n1的副本,从运行结果得知:虽然修改了数组n2,但是数组n1没有发生变化。
3.通过ndmin参数控制的最小维数
- 数组可以分为一维数组、二维数组和多维数组,通过ndmin参数可以控制数组的最小维数。无论给出的的数据的维数是多少,ndmin参数都会根据最小维数创建指定维数的数组。
修改数组的维数(04)
- ndmin=3,虽然给出的数组是一维的,但是同样会创建一个三维数组,程序代码如下:
import numpy as np
nd1 = [1, 2, 3]
nd2 = np.array(nd1, ndmin=3) #三维数组
print(nd2)
[[[1 2 3]]]
8.2.2 不同方式创建数组
1.创建指定维度和数据类型未初始化的数组(05)
- 创建指定维度和数据类型未初始化的数组主要使用empty()函数,程序代码如下:
import numpy as np
n = np.empty([2,3])
#z指定数据类型
#n = np.empty([2,3],dtype=int)
print(n)
[[0. 0.15 0.25]
[0.5 0.75 1. ]]
- 这里,数组元素为随机值,因为它们未被初始化。如果要改变数组类型,可以使用dtype参数,如整型,dtype=int。
2.创建指定维度(以0填充)的数组(06)
- 创建指定维度并以0填充的数组,主要使用zeros()函数,程序代码如下:
import numpy as np
n = np.zeros(3)
print(n)
[0. 0. 0.]
- 输出的结果默认是浮点型(float)。
3.创建指定维度(以1填充)的数组(07)
- 创建指定维度并以1填充的数组,主要使用ones()函数,程序代码如下:
import numpy as np
n = np.ones(3)
print(n)
[1. 1. 1.]
4.创建指定维度和类型的数组并以指定值填充(08)
- 创建指定维度和类型的数组并以指定值填充,主要使用full()函数,程序代码如下:
import numpy as np
n = np.full((3,3), 8)
print(n)
[[8 8 8]
[8 8 8]
[8 8 8]]
8.2.3 从数值范围创建数组
1.通过range()函数创建数组
- arrage()函数同Python内置range()函数类似,区别在于返回值,arrange()函数返回值是数组,而range()函数返回值是列表。arrange()函数的语法如下:
arrange([start,]stop[,step,],dtype=None)
- start:起始值,默认值为0
- stop:终止值(不包含)
- step:步长,默认值为1
- dtype:创建数组的数据类型,如果不设置数据类型,则使用输入数据的数据类型。
import numpy as np
n=np.arange(1,12,2)
print(n)
print(type(n))
[ 1 3 5 7 9 11]
<class 'numpy.ndarray'>
2.使用linspace()函数创建等差数列
linspace(start,stop,num=50,endpoint=True,retstep=False,dtype=None)
- start:序列的起始值。
- stop:序列的终止值,如果endpoint参数的值为True,则该值包含于数列中。
- num:要生成等步长的样本数量,默认值为50
- endpoint:如果值为True,数列中包含stop参数的值,反之则不包含。默认值为True。
- retstep:如果值为True,则生成的数组中会显示间距;反之则不显示。
- dtype:数组的数据类型。
import numpy as np
n1 = np.linspace(7500,10000,6)
n2 = np.linspace(7500,10000,6,endpoint=False)
print(n1)
print(n2)
- 运行程序,输出结果如下:
[ 7500. 8000. 8500. 9000. 9500. 10000.]
[7500. 7916.66666667 8333.33333333 8750. 9166.66666667
9583.33333333]
3.使用logspace()函数创建等比数列
numpy.logspace(start,stop,num=50,endpoint=True,base=10.0,dtype=None)
- start:序列的起始值。
- stop:序列的终止值,如果endpoint参数的值为True,则该值包含于数列中。
- num:要生成等步长的样本数量,默认值为50
- endpoint:如果值为True,数列中包含stop参数的值,反之则不包含。默认值为True。
- base:对数log的底数。
- dtype:数组的数据类型。
import numpy as np
#np.set_printoptions(threshold=np.inf)
#输出时打印不换行
np.set_printoptions(linewidth=800)
n = np.logspace(0,63,64,base=2,dtype='int')
# n = np.logspace(0,63,64,base=2,dtype='uint64')
#数组重塑8*8矩阵
print(n.reshape(8,8))
- 上述举例出现一个问题:后面大数出现负数,而且都是一样的,这是由于程序中指定的数据类型是int,是32位的,数据范围是-2147483648~2147483647,而我们计算的数据远远超出了这个范围,因此便出现了溢出现象。解决这一问题,需要指定数据类型为unit64(无符号整数,数据范围为0-1844674073709551615),关键代码如下:
n = np.logspace(0,63,64,base=2,dtype='uint64')
8.2.4 生成随机数组
- 随机数组的生成主要使用NumPy的random模块,下面介绍几种常见的随机生成数组的函数。
1.rand()函数
- rand()函数用于生成(0,1)之间的随机数组,传入一个值随机生成一维数组,传入一对值则随机生成二维数组,语法如下:
numpy.random.rand(d0,d1,d3,...,dn)
- 参数d0,d1,…,dn为整数,表示维度,可以为空。
随机生成0~1的数组
import numpy as np
n=np.random.rand(5)
print('随机生成0到1之间的一维数组:')
print(n)
n1=np.random.rand(2,5)
print('随机生成0到1之间的二维数组:')
print(n1)
随机生成0到1之间的一维数组:
[0.57869697 0.30188547 0.04030546 0.37590232 0.5425468 ]
随机生成0到1之间的二维数组:
[[0.56763724 0.20653114 0.54976305 0.39781119 0.44532154]
[0.60105384 0.24886826 0.0015031 0.98488654 0.84708016]]
2.randn()函数
- randn()函数用于从正态分布中返回随机生成的数组,语法如下:
numpy.random.randn(d0,d1,d2,d3,...,dn)
import numpy as np
n1=np.random.randn(5)
print('随机生成满足正态分布的一维数组:')
print(n1)
n2=np.random.randn(2,5)
print('随机生成满足正态分布的二维数组:')
print(n2)
随机生成满足正态分布的一维数组:
[-0.15211938 -1.03296299 1.06316179 -1.20923116 -0.55668442]
随机生成满足正态分布的二维数组:
[[ 1.01095022 -0.81314119 -0.45575704 1.00291623 0.57037931]
[-0.06936064 1.8009533 0.47733942 -0.02751161 0.65386916]]
3. randint()函数
- randint()函数于NumPy的arange()函数类似。randint()函数用于生成一定范围内的随机数组,左闭右开区间,语法如下:
numpy.random.randint(low,high=None,size=None)
- low:低值(起始值),整数,且当参数high不为空时,参数low应小于参数high;否则程序会出现错误。
- high:高值(终止值),整数。
- size:数组维数,整数或者元组,整数表示一维数组,元组表示多维数组。默认值为空,如果为空,则返回一个整数。
import numpy as np
n1=np.random.randint(1,3,10)
print('随机生成10个1到3之间且不包括3的整数:')
print(n1)
n2=np.random.randint(5,10)
print('size数组大小为空随机返回一个整数:')
print(n2)
n3=np.random.randint(5,size=(2,5))
print('随机生成5以内二维数组')
print(n3)
随机生成10个1到3之间且不包括3的整数:
[2 2 1 1 1 1 1 2 1 1]
size数组大小为空随机返回一个整数:
9
随机生成5以内二维数组
[[0 3 3 1 2]
[0 2 2 0 1]]
4.normal()函数
- normal()函数用于生成正态分布的函数,语法如下:
numpy.random.normal(loc,scale,size)
- loc:正态分布的均值,对应正态分布的中心。loc=0说明是一个以y轴对称轴的正态分布。
- scale:整体分布的标准差,对应正态分布的宽度,scale值越大,整体分布的曲线越“矮胖”;scale值越小,曲线越“高瘦”。
- size:表示数组维数。
import numpy as np
n = np.random.normal(0, 0.1, 10)
print(n)
[ 0.14080234 -0.20499852 0.03279486 0.06500545 -0.18000514 0.01893719
0.27595117 -0.10378904 0.18286385 0.03277625]
8.2.5 从已有的数组中创建数组
1.asarray()函数
- asarray()函数用于创建数组,其与array()函数类似,语法如下:
numpy.asarray(a,dtype=None,order=None)
- a:可以是列表、列表的元组、元组、元组的元组、元组的列表或多维数组。
- dtype:数组的数据类型。
- order:值为C和F,分别代表按行排列或按列排列,即数组元素在内存中的出现顺序。
import numpy as np #导入numpy模块
n1 = np.asarray([1,2,3]) #通过列表创建数组
n2 = np.asarray([(1,1),(1,2)]) #通过列表的元组创建数组
n3 = np.asarray((1,2,3)) #通过元组创建数组
n4= np.asarray(((1,1),(1,2),(1,3))) #通过元组的元组创建数组
n5 = np.asarray(([1,1],[1,2])) #通过元组的列表创建数组
print(n1)
print(n2)
print(n3)
print(n4)
print(n5)
[1 2 3]
[[1 1]
[1 2]]
[1 2 3]
[[1 1]
[1 2]
[1 3]]
[[1 1]
[1 2]]
2.frombuffer()函数
- NumPy的ndarray()数组对象不能像Python列表一样动态地改变其大小,在做数据采集时很不方便。下面介绍如何通过frombuffer()函数实现动态数组。frombuffer()函数接受buffer输入参数,以流的形式将读入的数据转换为数组。frombuffer()函数语法如下:
numpy.frombuffer(buffer,dtype=float,count=-1,offset=0)
- buffer:实现了__buffer__方法的对象。
- dtype:数组的数据类型。
- count:读取的数据数量,默认值为-1,表示读取所有数据。
- offset:读取的起始位置,默认值为0
将字符串”mingrisoft”转换为数组
import numpy as np
n=np.frombuffer(b'mingrisoft',dtype='S1')
print(n)
[b'm' b'i' b'n' b'g' b'r' b'i' b's' b'o' b'f' b't']
- 关键代码解析:当buffer参数值为字符串时,Python 3默认字符串是Unicode类型,所以要转成Byte string类型,需要在原字符串前面加上b
3.fromiter()函数
- fromiter()函数用于从可迭代对象中建立数组对象,语法如下:
numpy.fromiter(iterable,dtype,count=1)
- iterabel:可迭代对象。
- dtype:数组的数据类型。
- count:读取的数据数量,默认值为-1,表示读取所有数据。
import numpy as np
iterable = (x * 2 for x in range(5)) #遍历0~5并乘以2,返回可迭代对象
n = np.fromiter(iterable, dtype='int') #通过可迭代对象创建数组
print(n)
[0 2 4 6 8]
4.empty_like()函数
- empty_like()函数用于创建一个与给定数组具有相同维度和数据类型且未初始化的数组,语法如下:
numpy.empty_like(prototype,dtype=None,order='k',subok=True)
- prototype:给定的数组。
- dtype:覆盖结果的数据类型。
- order:指定数组的内存布局。其中C(按行)、F(按列)、A(原顺序)、K(数据元素的内存中的出现顺)。
- subok:默认情况下,返回的数组被强制为基类数组。如果值为True,则返回子类。
import numpy as np
n = np.empty_like([[1, 2], [3, 4]])
print(n)
[[ 793213571 -262225594]
[-1944896189 -1117814368]]
5.zeros_like()函数
- zeros_like()函数用于创建一个与给定数组维度和数据类型相同,并以0填充的数组,程序代码如下:
import numpy as np
n = np.zeros_like([[0.1,0.2,0.3], [0.4,0.5,0.6]])
print(n)
[[0. 0. 0.]
[0. 0. 0.]]
6.ones_like()函数
- ones_like()函数用于创建一个与给定数组维度和数据类型相同,并以1填充的数组,程序代码如下:
import numpy as np
n = np.ones_like([[0.1,0.2,0.3], [0.4,0.5,0.6]])
print(n)
[[1. 1. 1.]
[1. 1. 1.]]
7.full_like()函数
- full_like()函数用于创建一个与给定数组维度和数据类型相同,并以指定值填充的数组,语法如下:
numpy.full_like(a,fill_value,dtype=None,order='K',subok=True)
- a:给定的数组。
- fill_value:填充值。
- dtype:数组的数据类型,默认值为None,则使用给定的数据类型。
- order:指定数组的内存布局。其中C(按行)、F(按列)、A(原顺序)、K(数据元素的内存中的出现顺)。
- subok:默认情况下,返回的数组被强制为基类数组。如果值为True,则返回子类。
创建以指定值”0.2“填充的数组
import numpy as np
a = np.arange(6) #创建一个数组
n1 = np.full_like(a, 1) #创建一个与数组a维度和数据类型相同的数组,以1填充
n2 = np.full_like(a,0.2) #创建一个与数组a维度和数据类型相同的数组,以0.2填充
#创建一个与数组a维度和数据类型相同的数组,以0.2填充,浮点型
n3 = np.full_like(a, 0.2, dtype='float')
print(n1)
print(n2)
print(n3)
[1 1 1 1 1 1]
[0 0 0 0 0 0]
[0.2 0.2 0.2 0.2 0.2 0.2]
8.3 数组的基本操作
8.3.1 数据类型
-
在对数组进行基本操作前,首先了解一下NumPy的数据类型。NumPy的数据类型增加了更多种类的数值类型,如表8.1所示。为了区别Python数据类型,像bool、int、float、complex、str等数据类型的名称末尾都加了短下划线”_”
- 每一种数据类型都有相应的数据转换函数。举例如下:
- 在创建ndarray数组时,可以直接指定数值类型,关键代码如下:
a = np.arange(8,dtype=float)
a
8.3.2 数值运算
-
不用编写循环即可对数据执行批量运算,这就是NumPy数组运算的特点,NumPy称之为矢量化。大小相等的数组之间的任何算术运算NumPy都可以实现。本节主要介绍简单的数组运算,如加、减、乘、除、幂运算等。下面创建两个简单的NumPy数组,即n1和n2,数组n1包括元素1和2,数组n2包括元素3和4,如图8.14所示。接下来实现这两个数组的运算。
数值的减法、乘法和除法运算
import numpy as np
n1=np.array([1,2]) #创建一维数组
n2=np.array([3,4])
print(n1-n2) #减法运算
print(n1*n2) #乘法运算
print(n1/n2) #除法运算
[-2 -2]
[3 8]
[0.33333333 0.5 ]
3.幂运算
import numpy as np
n1=np.array([1,2]) #创建一维数组
n2=np.array([3,4])
print(n1**n2) #幂运算
[ 1 16]
4.比较运算
import numpy as np
n1=np.array([1,2]) #创建一维数组
n2=np.array([3,4])
print(n1>=n2) #大于等于
print(n1==n2) #等于
print(n1<=n2) #小于等于
print(n1!=n2) #不等于
[False False]
[False False]
[ True True]
[ True True]
5.数组的标量运算
import numpy as np
n1 = np.linspace(7500,10000,6,dtype='int') #创建等差数列数组
print(n1)
print(n1/1000) #米转换为公里
[ 7500 8000 8500 9000 9500 10000]
[ 7.5 8. 8.5 9. 9.5 10. ]
8.3.3 数组的索引和切片
- NumPy数组元素是通过数组的索引和切片来访问和修改的,因此索引和切片是NumPy中最重要、最常用的操作。
1.索引
import numpy as np
n1=np.array([1,2,3]) #创建一维数组
print(n1[0])
n1=np.array([[1,2,3],[4,5,6]]) #创建二维数组
print(n1[1][2])
1
6
2.切片式索引
- 数组的切片可以理解为对数组的分割,按照等分或者不等分,将一个数组切割为多个片段,它与Python中列表的切片操作一样。NumPy中的切片用冒号分隔切片参数来进行切片操作,语法如下:
[start:stop:step]
- start:起始索引。
- stop:终止索引。
- step:步长。
import numpy as np
n1=np.array([1,2,3]) #创建一维数组
print(n1[0])
print(n1[1])
print(n1[0:2])
print(n1[1:])
print(n1[:2])
1
2
[1 2]
[2 3]
[1 2]
常用的切片式索引操作
import numpy as np
n = np.arange(10) #使用arange函数创建一维数组
print(n)
print(n[:3]) # 0 1 2
print(n[3:6]) # 3 4 5
print(n[6:]) # 6 7 8 9
print(n[::]) # 0 1 2 3 4 5 6 7 8 9
print(n[:]) # 0 1 2 3 4 5 6 7 8 9
print(n[::2]) # 0 2 4 6 8
print(n[1::5]) # 1 6
print(n[2::6]) # 2 8
#start、stop、step为负数时
print(n[::-1]) # 9 8 7 6 5 4 3 2 1 0
print(n[:-3:-1]) # 9 8
print(n[-3:-5:-1]) # 7 6
print(n[-5::-1]) # 5 4 3 2 1 0
3.二维数组索引
-
二维数组索引可以使用array[n,m]的方式,以逗号分隔,表示第n个数组的,第m个元素。
import numpy as np
#创建3行4列的二维数组
n=np.array([[0,1,2,3],[4,5,6,7],[8,9,10,11]])
print(n)
print(n[1])
print(n[1,2])
print(n[-1])
[[ 0 1 2 3]
[ 4 5 6 7]
[ 8 9 10 11]]
[4 5 6 7]
6
[ 8 9 10 11]
4.二维数组切片索引
import numpy as np
#创建3行3列的二维数组
n=np.array([[1,2,3],[4,5,6],[7,8,9]])
print(n[:2,1:])
print(n[1,:2])
print(n[:2,2])
print(n[:,:1])
[[2 3]
[5 6]]
[4 5]
[3 6]
[[1]
[4]
[7]]
8.3.4 数组重塑
- 数组重塑实际上式更改数组的形状,例如,将原来2行3列的数组重塑为3行4列的数组。在NumPy中主要使用reshape()方法,该方法用于改变数组的形状。
1.一维数组重塑
import numpy as np
n=np.arange(6) #创建一维数组
print(n)
n1=n.reshape(2,3) #将数组重塑为2行3列的二维数组
print(n1)
n=np.array(['床','前','明','月','光','疑','是','地','上','霜','举','头','望','明','月','低','头','思','故','乡'])
n1=n.reshape(4,5)
print(n1)
[0 1 2 3 4 5]
[[0 1 2]
[3 4 5]]
[['床' '前' '明' '月' '光']
['疑' '是' '地' '上' '霜']
['举' '头' '望' '明' '月']
['低' '头' '思' '故' '乡']]
2.多维数组重塑
import numpy as np
n=np.array([[0,1,2],[3,4,5]]) #创建二维数组
print(n)
n1=n.reshape(3,2) #将数组重塑为3行2列的二维数组
print(n1)
[[0 1 2]
[3 4 5]]
[[0 1]
[2 3]
[4 5]]
3.数组转置
import numpy as np
n = np.arange(24).reshape(4,6) #创建4行6列的二维数组
print(n)
print(n.T) #T属性行列转置
[[ 0 1 2 3 4 5]
[ 6 7 8 9 10 11]
[12 13 14 15 16 17]
[18 19 20 21 22 23]]
[[ 0 6 12 18]
[ 1 7 13 19]
[ 2 8 14 20]
[ 3 9 15 21]
[ 4 10 16 22]
转换客户销售数据
import numpy as np
n = np.array([['A',100],['B',200],['C',300],['D',400],['E',500]])
print(n)
print(n.T) #T属性行列转置
print(n.transpose()) #transpose()函数行列转置
[['A' '100']
['B' '200']
['C' '300']
['D' '400']
['E' '500']]
[['A' 'B' 'C' 'D' 'E']
['100' '200' '300' '400' '500']]
[['A' 'B' 'C' 'D' 'E']
['100' '200' '300' '400' '500']]
8.3.5 数组的增、删、改、查
1.数组的增加
- 数组的增加可以按照水平方向增加数据,也可以按照垂直方向增加数据。水平方向增加数据主要使用hstack()函数,垂直方向增加数据主要使用vstack()函数。
import numpy as np
#创建二维数组
n1=np.array([[1,2],[3,4],[5,6]])
n2=np.array([[10,20],[30,40],[50,60]])
print(np.hstack((n1,n2))) #水平方向增加数据
print(np.vstack((n1,n2))) #垂直方向增加数据
[[ 1 2 10 20]
[ 3 4 30 40]
[ 5 6 50 60]]
[[ 1 2]
[ 3 4]
[ 5 6]
[10 20]
[30 40]
[50 60]]
2.数组的删除
- 数组的删除主要使用delete()方法。
import numpy as np
#创建二维数组
n1=np.array([[1,2],[3,4],[5,6]])
print(n1)
n2=np.delete(n1,2,axis=0) #删除第3行
n3=np.delete(n1,0,axis=1) #删除第1列
n4=np.delete(n1,(1,2),0) #删除第2行和第3行
print('删除第3行后的数组:','\n',n2)
print('删除第1列后的数组:','\n',n3)
print('删除第2行和第3行后的数组:','\n',n4)
[[1 2]
[3 4]
[5 6]]
删除第3行后的数组:
[[1 2]
[3 4]]
删除第1列后的数组:
[[2]
[4]
[6]]
删除第2行和第3行后的数组:
[[1 2]]
3.数组的修改
import numpy as np
#创建二维数组
n1=np.array([[1,2],[3,4],[5,6]])
print(n1)
n1[1]=[30,40] #修改第2行数组[3,4]为[30,40]
n1[2][1]=88 #修改第3行第3个元素6为88
print('修改后的数组:','\n',n1)
[[1 2]
[3 4]
[5 6]]
修改后的数组:
[[ 1 2]
[30 40]
[ 5 88]]
4.数组的查询
- 数组的查询同样可以使用索引和切片方法来获取指定范围的数组或数组元素,还可以通过where()函数查询符合条件的数组或数组元素。where()函数语法格式如下:
numpy.where(condition,x,y)
- 上述语法,第一个参数为第一个布尔数组,第二个参数和第三个参数可以是标量也可以是数组。满足条件(参数condition),输出参数x,不满足条件输出参数y。
import numpy as np
n1 = np.arange(10) #创建一个一维数组
print(n1)
print(np.where(n1>5,2,0)) #大于5输出2,不大于5输出0
n2=n1[np.where(n1>5)]
print(n2)
[0 1 2 3 4 5 6 7 8 9]
[0 0 0 0 0 0 2 2 2 2]
[6 7 8 9]
8.4 数据矩阵的基本操作
- 在数学中经常可以看到矩阵,而在程序中常用的是数组,可以简单的理解为,矩阵是数学的概念,而数组是计算机程序设计领域的概念。在NumPy中,矩阵是数组的分支,数组和矩阵有些时候是通用的,二维数组也称矩阵。
8.4.1 创建矩阵
-
NumPy函数库中存在两种不同的数据类型(矩阵matrix和数组array),它们都可以用于处理行列表示的数组元素,虽然它们表面上看起来很相似,但是在这两种数据类型上执行相同的数学运算,可能得到不同的结果。
创建简单矩阵
- 使用mat()函数创建矩阵,程序代码如下:
import numpy as np
a = np.mat('5 6;7 8')
b = np.mat([[1, 2], [3, 4]])
print(a)
print(b)
print(type(a))
print(type(b))
n1 = np.array([[1, 2], [3, 4]])
print(n1)
print(type(n1))
[[5 6]
[7 8]]
[[1 2]
[3 4]]
<class 'numpy.matrix'>
<class 'numpy.matrix'>
[[1 2]
[3 4]]
<class 'numpy.ndarray'>
- 从运行结果得知:mat()函数创建的是矩阵类型,array()函数创建的是数组类型,而用mat()函数创建的矩阵才能进行一些线性代数的操作。
使用mat()函数创建常见的矩阵
import numpy as np
# 创建一个3*3的零矩阵
data1 = np.mat(np.zeros((3,3)))
print('3*3的零矩阵:')
print(data1)
# 创建一个2*4的1矩阵
data1 = np.mat(np.ones((2,4)))
print('2*4的1矩阵:')
print(data1)
#使用rand()函数创建一个3*3在0~1之间随机产生的二维数组
data1 = np.mat(np.random.rand(3,3))
print('3*3在0~1之间随机产生的二维数组:')
print(data1)
#创建一个1~8之间的随机整数矩阵
data1 = np.mat(np.random.randint(1,8,size=(3,5)))
print('1~8之间的随机整数矩阵:')
print(data1)
#创建对角矩阵
print('对角矩阵:')
data1 = np.mat(np.eye(2,2,dtype=int)) #2*2对角矩阵
print(data1)
data1 = np.mat(np.eye(4,4,dtype=int)) #4*4对角矩阵
print(data1)
#创建对角线矩阵
print('对角线矩阵:')
a = [1,2,3]
data1 = np.mat(np.diag(a)) #对角线1、2、3矩阵
print(data1)
b = [4,5,6]
data1 = np.mat(np.diag(b)) #对角线4、5、6矩阵
print(data1)
3*3的零矩阵:
[[0. 0. 0.]
[0. 0. 0.]
[0. 0. 0.]]
2*4的1矩阵:
[[1. 1. 1. 1.]
[1. 1. 1. 1.]]
3*3在0~1之间随机产生的二维数组:
[[0.0399538 0.45666733 0.63364134]
[0.03244868 0.63405799 0.00862924]
[0.21770499 0.95343874 0.93665855]]
1~8之间的随机整数矩阵:
[[6 1 7 7 7]
[1 4 4 7 6]
[3 7 7 4 1]]
对角矩阵:
[[1 0]
[0 1]]
[[1 0 0 0]
[0 1 0 0]
[0 0 1 0]
[0 0 0 1]]
对角线矩阵:
[[1 0 0]
[0 2 0]
[0 0 3]]
[[4 0 0]
[0 5 0]
[0 0 6]]
mat()函数只适用于二维矩阵,维数超过2以后,mat()函数就不适用了,从这一点来看array()函数更具通用性。
8.4.2 矩阵运算
矩阵加法运算
import numpy as np
#创建矩阵
data1= np.mat([[1, 2], [3, 4],[5,6]])
data2=np.mat([1,2])
print(data1+data2) #矩阵加法运算
[[2 4]
[4 6]
[6 8]]
矩阵减法运算
import numpy as np
#创建矩阵
data1= np.mat([[1, 2], [3, 4],[5,6]])
data2=np.mat([1,2])
print(data1-data2) #矩阵减法法运算
print(data1/data2) #矩阵除法运算
[[0 0]
[2 2]
[4 4]]
[[1. 1.]
[3. 2.]
[5. 3.]]
修改矩阵并进行乘法运算
import numpy as np
#创建矩阵
data1= np.mat([[1, 2], [3, 4],[5,6]])
data2=np.mat([[1,2],[3,4]])
print(data1*data2) #矩阵乘法运算
[[ 7 10]
[15 22]
[23 34]]
数组相乘与数组点乘比较
- 数组运算和矩阵运算的一个关键区别是矩阵使用的点乘。点乘,也称点积,是数组中元素对应位置一一相乘之后求和的操作,在NumPy中专门提供了点乘方法,即dot()方法,该方法返回的是两个数组的点积。
import numpy as np
#创建数组
n1 = np.array([1, 2, 3])
n2= np.array([[1, 2, 3], [1, 2, 3], [1, 2, 3]])
print('数组相乘结果为:','\n', n1*n2) #数组相乘
print('数组点乘结果为:','\n', np.dot(n1, n2)) #数组点乘
print(np.multiply(n1,n2))
数组相乘结果为:
[[1 4 9]
[1 4 9]
[1 4 9]]
数组点乘结果为:
[ 6 12 18]
[[1 4 9]
[1 4 9]
[1 4 9]]
矩阵元素之间的相乘运算
- 要实现矩阵对应元素之间的相乘可以使用multiply()函数,程序代码如下:
import numpy as np
n1 = np.mat('1 3 3;4 5 6;7 12 9') # #创建矩阵,使用分号隔开数据
n2 = np.mat('2 6 6;8 10 12;14 24 18')
print('矩阵相乘结果为:\n',n1*n2) #矩阵相乘
print('矩阵对应元素相乘结果为:\n',np.multiply(n1,n2))
矩阵相乘结果为:
[[ 68 108 96]
[132 218 192]
[236 378 348]]
矩阵对应元素相乘结果为:
[[ 2 18 18]
[ 32 50 72]
[ 98 288 162]]
8.4.3 矩阵转换
1.矩阵转置
import numpy as np
n1 = np.mat('1 3 3;4 5 6;7 12 9') # #创建矩阵,使用分号隔开数据
print('矩阵转置结果为:\n',n1.T) #矩阵转置
矩阵转置结果为:
[[ 1 4 7]
[ 3 5 12]
[ 3 6 9]]
2.矩阵求逆
import numpy as np
n1 = np.mat('1 3 3;4 5 6;7 12 9') # #创建矩阵,使用分号隔开数据
print('矩阵的逆矩阵结果为:\n',n1.I) #逆矩阵
矩阵的逆矩阵结果为:
[[-0.9 0.3 0.1 ]
[ 0.2 -0.4 0.2 ]
[ 0.43333333 0.3 -0.23333333]]
版权声明:本文为Triumph19原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。