文章目录
- 一.基础
- 1.Ndarray对象
- 2.数据类型
- 二.数组
- 1.数组属性
- (1)arange
- (2)shape
- (3)ndim
- (4)itemsize
- 2.创建数组
- (1)empty
- (2)zero
- (3)ones
- (4)zeros/ones_like
- (5)identity
- 3.从已有的数组创建数组
- (1)作为数组asarray
- (2)frombuffer
- (3)fromiter
- 4.从数值范围创建数组
- (1)linspace
- (2)logspace
- 三.切片和索引
- 1.基础
- 2.高级索引
- 四.迭代数组
- 1.按行访问
- 2.按列访问:先转置
- 3.按行迭代
- 4.按列迭代
- 5.迭代过程中数组元素的修改
- 6.flags参数
- 五.广播
- 六.数组操作
- 1.修改数组的形状
- (1)reshape(arr,newshape,order)
- (2)flat
- (3)flatten
- (4)ravel
- 2.翻转数组(转置)
- (1)三维数组
- (2)rollaxis(arr,axis,start)
- (3)swapaxes
- (4)查看元素位置
- 3.修改数组维度
- (1)numpy.broadcast
- (2)numpy.broadcast_to
- (3)numpy.expand_dims
- (4)numpy.squeeze
- 4.连接数组
- (1)concatenate
- (2)stack
- (3)hstack
- (4)vstack
- 5.分割数组
- (1)split(数组,切割方式,行/列)
- (2)hsplit
- (3)vsplit
- 6.数组元素的添加与删除
- (1)append
- (2)insert
- (3)delete
- (4)unique
- 七.位运算
- 1.bitwise_and
- 2.bitwise_or
- 3.invert
- 4.left_shift
- 5.right_shift
- 八.函数
- (一)字符串函数
- 1.char.add
- 2.char.multiply
- 3.char.center
- 4.char.capitalize
- 5.char.title
- 6.char.lower
- 7.char.upper
- 8.char.split
- 9.char.splitlines
- 10.char.strip
- 11.char.join
- 12.char.replace
- 13.char.encode/decode
- (二)数学函数
- 1.三角函数
- 2.舍入函数
- (三)算术函数
- 1.add
- 2.subtract
- 3.multiply
- 4.divide
- ### 5.reciprocal
- 6.power
- 7.mod
- (四)统计函数
- 1.amin/amax
- 2.ptp
- 3.percentile
- 4.median
- 5.mean
- 6.average
- 7.方差var与标准差std
- (五)排序、条件筛选函数
- 1.sort
- 2.argsort
- 3.lexsort
- 4.sort_complex
- 5.partition
- 6.argpartition
- 7.argmax和argmin
- 8.nonzero
- 9.where
- 10.extract
- 九.字节交换
- 1.map与hex
- 2.字节交换
- 十.副本和视图
- 1.视图
- 2.副本
- 十一.线性代数
- 1.dot
- 2.vdot
- 3.inner
- 4.matmul
- 5.linalg.det
- 6.linalg.slove
- 7.linalg.inv
- 十二.I/O
- 1.save/load
- 2.savez/load
- 3.savetxt/loadtxt
- 十三.Matplotlib
- 1.plot/show
- 2.格式化字符
- 3.绘制正弦波
- 4.subpolt
- 5.bar
- 6.histogram
- 7.plt
注:
1.本文因内容较多,在某些具体函数上可能不够细化
2.本文的很多内容都是由实验结果推导的,可能存在一定问题
3.后续若有补充或修改会及时更新
NumPy(Numerical Python)是Python的一种开源的数值计算扩展。可用来存储和处理大型矩阵,支持大量的维度数组与矩阵运算,此外也针对数组运算提供大量的数学函数库。
一.基础
1.Ndarray对象
N维数组对象Ndarray是一系列同类型数据的集合
包括:指针、数据类型data-type(dtype)、表示数据形状的元组(shape)、跨度元组(stride)
创建Ndarray对象只需调用array函数即可
numpy.array(object,dtype,copy,order,subok,ndmin)
object:数组或嵌套的数列
dtype:数据类型,可选
copy:是否需要复制,布尔类型,可选
order:创建数组的样式,C为行方向,F为列方向,A为任意方向(默认)
subok:默认返回一个与基类类型一致的数组
ndmin:指定生成数组的最小维度
import numpy as np
a=np.array([1,2,3])
print(a) # [1 2 3]
import numpy as np
a1=np.array([1,2,3]) # [1 2 3]
a2=np.array([1,2,3],ndmin=1) # [1 2 3]
a3=np.array([1,2,3],ndmin=2) # [[1 2 3]]
a4=np.array([1,2,3],ndmin=3) # [[[1 2 3]]]
b1=np.array([[1,2],[3,4]])
"""
[[1 2]
[3 4]]
"""
b2=np.array([[1,2],[3,4]],ndmin=2)
"""
[[1 2]
[3 4]]
"""
b3=np.array([[1,2],[3,4]],ndmin=3)
"""
[[[1 2]
[3 4]]]
"""
2.数据类型
(1)基本类型
(2)数据类型对象dtype
numpy.dtype(object,align,copy)
object:要转换为的数据类型对象
align:布尔类型,为True表示填充字段使其类似C的结构体
copy:复制dtype对象,布尔类型,如果为False则是对内置数据类型对象的引用
在numpy中可指明数据的类型、大小,数据的字节顺序等
import numpy as np
a=np.dtype(np.int32)
print(a) # int32
a1=np.dtype("i4")
print(a) # int32
# 对应关系:i1-int8 i2-int16 i4-int32 i8-int64
# 即:ik-int8k
<小端:数据在内存中的实际存储顺序从小端(内存低地址)开始存储
>大端:数据在内存中的实际存储顺序从大端(内存高地址)开始存储
一般操作系统都是小端,通讯协议是大端
import numpy as np
a=np.dtype("<i4") # 指明数据的字节顺序:小端
print(a) # int32
应用
import numpy as np
a=np.dtype([("age",np.int8)])
print(a) # [('age', 'i1')]
student=np.dtype([("name","S4"),("age","i1")]) # 创建student类型,S4表示name为字符串前4个字符
print(student) # [('name', 'S4'), ('age', 'i1')]
a=np.array([("jack",18),("peter",19)],dtype=student) # 指明student类型
print(a) # [(b'jack', 18) (b'pete', 19)]
二.数组
1.数组属性
(1)arange
返回一个有终点和起点的固定步长的排列
np.arange(start,stop(不含),step)
start:默认为0
step:步长,默认为1
import numpy as np
a1=np.arange(1) # [0]
a2=np.arange(1,5) # [1 2 3 4]
a3=np.arange(1,9,1) # [1 2 3 4 5 6 7 8]
a4=np.arange(1,9,2) # [1 3 5 7]
a5=np.arange(1,4,0.5) # [1. 1.5 2. 2.5 3. 3.5]
# n.0一般会写作n.空格
(2)shape
返回一个元组:(行数,列数)
import numpy as np
a=np.array([[1,2,3],[4,5,6]])
print(a.shape) # (2, 3)
print(a)
"""
[[1 2 3]
[4 5 6]]
"""
①通过shape调整数组大小
import numpy as np
a=np.array([[1,2,3],[4,5,6]])
print(a)
"""
[[1 2 3]
[4 5 6]]
"""
a.shape=(3,2)
print(a)
"""
[[1 2]
[3 4]
[5 6]]
"""
②通过reshape调整数组大小
import numpy as np
a=np.array([[1,2,3],[4,5,6]])
print(a.shape) # (2, 3)
b=a.reshape(3,2)
print(b.shape) # (3, 2)
import numpy as np
a=np.arange(12)
print(a) # [ 0 1 2 3 4 5 6 7 8 9 10 11]
b=a.reshape(2,2,3) # 分2块显示,每块2行3列
print(b)
"""
[[[ 0 1 2]
[ 3 4 5]]
[[ 6 7 8]
[ 9 10 11]]]
"""
③通过resize调整数组大小
import numpy as np
a=np.array([[1,2,3],[4,5,6]])
print(a)
"""
[[1 2 3]
[4 5 6]]
"""
b=np.resize(a,(3,2)) # 改为3行2列
print(b)
"""
[[1 2]
[3 4]
[5 6]]
"""
当新形状小于原形状时,resize会删除多余元素;当新形状大于原形状时,resize会重复出现元素。而reshape会抛出ValueError异常
import numpy as np
a=np.array([[1,2,3],[4,5,6]])
print(a)
"""
[[1 2 3]
[4 5 6]]
"""
b=np.resize(a,(3,1))
print(b)
"""
[[1]
[2]
[3]]
"""
b=np.resize(a,(5,5))
print(b)
"""
[[1 2 3 4 5]
[6 1 2 3 4]
[5 6 1 2 3]
[4 5 6 1 2]
[3 4 5 6 1]]
"""
(3)ndim
返回数组的维数/维度/秩/轴的数量
import numpy as np
a=np.arange(24)
print(a) # [ 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23]
print(a.ndim) # 1
b=np.array([[1,2,3],[4,5,6]])
print(b.ndim) # 2
print(b)
"""
[[1 2 3]
[4 5 6]]
"""
c=a.reshape(2,4,3) # 分为2块,每块4行3列
print(c.ndim) # 3
print(c)
"""
[[[ 0 1 2]
[ 3 4 5]
[ 6 7 8]
[ 9 10 11]]
[[12 13 14]
[15 16 17]
[18 19 20]
[21 22 23]]]
"""
(4)itemsize
以字节(8bit)的形式返回数组中每一个元素的大小
import numpy as np
a=np.array([1,2,3,4,5],dtype=np.int8)
print(a) # [1 2 3 4 5]
print(a.itemsize) # 1
a=np.array([1,2,3,4,5],dtype=np.int16)
print(a.itemsize) # 2
a=np.array([1,2,3,4,5],dtype=np.float64)
print(a.itemsize) # 8
b=np.dtype("i4")
print(b.itemsize) # 4
2.创建数组
(1)empty
创建一个(几块,行数,列数)、指定类型的空数组(数值随机)
import numpy as np
a=np.empty([2,2,3],dtype=int)
print(a)
"""
[[[4128860 6029375 3801156]
[7340124 7602297 7274600]]
[[6226030 7471216 6619228]
[6553710 50 0]]]
"""
(2)zero
创建指定类型的零数组
import numpy as np
# 以浮点数的形式输出5个全为0的数
a=np.zeros(5) # 一维,5个数
print(a) # [0. 0. 0. 0. 0.]
# 转为整数
a=np.zeros(5,dtype=int)
print(a) # [0 0 0 0 0]
# 指定转换类型
a=np.zeros((2,2),dtype=[("name","i4"),("age","i4")])
print(a)
"""2行2列,每组分别为name和age
[[(0, 0) (0, 0)]
[(0, 0) (0, 0)]]
"""
(3)ones
创建指定类型的全1数组
import numpy as np
a=np.ones(5)
print(a) # [1. 1. 1. 1. 1.]
a=np.ones(5,dtype=int)
print(a) # [1 1 1 1 1]
a=np.ones((2,3),dtype=[("name","i4"),("age","i4")])
print(a)
"""
[[(1, 1) (1, 1) (1, 1)]
[(1, 1) (1, 1) (1, 1)]]
"""
(4)zeros/ones_like
创建一个与给定数组具有相同形状的数组
import numpy as np
a=np.array([[1,2,3],[4,5,6]])
b=np.zeros_like(a)
print(b)
"""
[[0 0 0]
[0 0 0]]
"""
c=np.ones_like(a)
print(c)
"""
[[1 1 1]
[1 1 1]]
"""
(5)identity
创建单位矩阵
import numpy as np
print(np.identity(4))
"""
[[1. 0. 0. 0.]
[0. 1. 0. 0.]
[0. 0. 1. 0.]
[0. 0. 0. 1.]]
"""
3.从已有的数组创建数组
(1)作为数组asarray
将X转为数组
import numpy as np
a=[1,2,3]
print(a) # 列表[1, 2, 3]
b=np.asarray(a)
print(b) # 数组[1 2 3]
(2)frombuffer
通过buffer传入参数,将其转化为ndarray对象
其中必须指明dtype,大小为buffer传入参数的最小公倍数
import numpy as np
a=b"hellohello"
b=np.frombuffer(a,dtype="S1") # 将hellohello十个字符,每个一组
b2=np.frombuffer(a,dtype="S2") # 每两个一组
b3=np.frombuffer(a,dtype="S5") # 每5个一组
b4=np.frombuffer(a,dtype="S10") # 每10个一组
print(b) # [b'h' b'e' b'l' b'l' b'o' b'h' b'e' b'l' b'l' b'o']
print(b2) # [b'he' b'll' b'oh' b'el' b'lo']
print(b3) # [b'hello' b'hello']
print(b4) # [b'hellohello']
关于这个b:buffer不能接收字符串,python3的str默认是Unicode类型,要转换成byte-string才能传入(前面加b)
import numpy as np
a=b"jack"
b="jack"
print(a) # b'jack'
print(type(a)) # <class 'bytes'>
print(b) # jack
print(type(b)) # <class 'str'>
c=np.frombuffer(a,dtype="S2") # 传入bytes
print(c) # [b'ja' b'ck']
print(type(c)) # <class 'numpy.ndarray'>
c=np.frombuffer(b,dtype="S2") # 传入str
# TypeError: a bytes-like object is required, not 'str'
(3)fromiter
from-iteration来自于迭代:从可迭代对象中建立ndarray对象,返回一维数组
import numpy as np
a=range(5) # 0~4
print(a) # range(0, 5)
b=np.fromiter(a,dtype=int)
print(b) # [0 1 2 3 4]
4.从数值范围创建数组
(1)linspace
创建等差数列
linspace(start,stop,num,endpoint,retstep,dtype)
从start到stop(含)生成num个数,默认浮点类型,生成的是等差数列组成的数组
import numpy as np
a=np.linspace(1,10,5) # 从1到10,出5个数
print(a) # [ 1. 3.25 5.5 7.75 10. ]
# 公差2.25
如果强制设置int型,可能不再是等差数列
import numpy as np
a=np.linspace(1,10,5,dtype=int) # 从1到10,出5个数
print(a) # [ 1 3 5 7 10]
# 只保留了整数部分
endpoint=False不包含stop
import numpy as np
a=np.linspace(1,10,5,endpoint=False) # 从1到9,出5个数
print(a) # [1. 2.8 4.6 6.4 8.2]
# 公差1.8
# 公差取值是使最后一个数不超过且不等于stop的最大的数
# endpoint=True包含stop(默认)
retstep=True在输出时会指明公差
import numpy as np
a=np.linspace(1,10,5,endpoint=False,retstep=True) # 从1到9,出5个数
print(a) # (array([1. , 2.8, 4.6, 6.4, 8.2]), 1.8)
# 公差1.8
结合reshape
import numpy as np
a=np.linspace(1,10,10) # 从1到10(含),生成10个数(默认浮点)
print(a) # [ 1. 2. 3. 4. 5. 6. 7. 8. 9. 10.]
b=a.reshape([5,2]) # 转换为5行2列
print(b)
"""
[[ 1. 2.]
[ 3. 4.]
[ 5. 6.]
[ 7. 8.]
[ 9. 10.]]
"""
(2)logspace
创建等比数列
logspace(start,stop,num,endpoint,base,dtype)
base:设置log的底数,默认为10
num:输出数据个数,默认为50
结果输出默认浮点型,若转为整型可能破坏等比数列
如下例,2为底数(base),一共输出10个数(num),分别是2的1次幂(start)到2的10次幂(stop)
import numpy as np
a=np.logspace(1,10,10,base=2)
print(a) # [ 2. 4. 8. 16. 32. 64. 128. 256. 512. 1024.]
若num设置为其他值,为保证输出的是等比数列。输出的开头一定是basestart,结尾一定是basestop(在endpoint=True包含结尾时),中间等比例划分
下面对中间待填写的数字进行推导
# 例
import numpy as np
a=np.logspace(1,8,4,base=2)
print(a)
输出:(共4个)
第一个:21=2.
待填写第一个:待计算
待填写第二个:待计算
最后一个:28=256.
下面直接推导一般情况(num>2时),设公比为baseq
第一个basestart
待填写第一个baseq+start
待填写第二个base2q+start
待填写最后一个base(num-2)q+start
最后一个basestop
有等式base(num-2)q+start+q=basestop成立
解得q=(stop-start)/(num-1)
即
待填写第一个=baseq+start=base(stop-start)/(num-1)+start
待填写第二个=base2q+start=base2*[(stop-start)/(num-1)]+start
待填写第k个=basekq+start=basek*[(stop-start)/(num-1)]+start
回到例题
待填写第一个=23.33333…=10.0793684
待填写第二个=25.66666…=50.79683366
import numpy as np
a=np.logspace(1,8,4,base=2)
print(a)
# [ 2. 10.0793684 50.79683366 256. ]
三.切片和索引
1.基础
(1)slice(start,stop(不含),step)
此方法先指明切片方式,然后进行切片
import numpy as np
a=np.arange(10)
print(a) # [0 1 2 3 4 5 6 7 8 9]
b=slice(3,7,2) # b是一个切片行为:从3到7(不含),间隔为2
print(a[b]) # 指明切谁
# 输出: [3 5]
(2)通过冒号直接切片
import numpy as np
a=np.arange(10)
print(a[3:7:2]) # [3 5]
关于参数
1个参数:返回该索引对应的元素(类似于数组索引)
2个参数:步长默认为1
“n:”:从n到最后一个元素(含)
(3)多维数组
import numpy as np
a=np.array([[1,2,3],[4,5,6],[7,8,9]])
print(a)
"""
[[1 2 3]
[4 5 6]
[7 8 9]]
"""
print(a[1]) # [4 5 6]
print(a[0][1]) # 2
print(a[1:])
"""
[[4 5 6]
[7 8 9]]
"""
打印指定列
import numpy as np
a=np.array([[1,2,3],[4,5,6],[7,8,9]])
print(a)
"""
[[1 2 3]
[4 5 6]
[7 8 9]]
"""
print(a[...,0]) # [1 4 7]
print(a[...,1:])
"""
[[2 3]
[5 6]
[8 9]]
"""
2.高级索引
(1)整数数组索引
通过a[ [x1,x2,x3] , [y1,y2,y3] ] 获取数组a[x1][y1]、a[x2][y2]、a[x3][y3]元素组成新数组
import numpy as np
a=np.array([[1,2,3],[4,5,6],[7,8,9]])
print(a)
"""
[[1 2 3]
[4 5 6]
[7 8 9]]
"""
# 获取指定元素
print(a[0][0],a[1][2],a[0][2]) # 1 6 3
# 获取指定元素组成数组
print(a[[0,1,0],[0,2,2]]) # [1 6 3]
复杂索引
①
b=np.array([[x1,x2]])
c=np.array([[y1,y2]])
arr=a[b,c] # b的元素作为行,c的元素作为列
输出一维数组:[[x1,y1 x2,y2]]
import numpy as np
a=np.array([[1,2,3],[4,5,6],[7,8,9]])
print(a[0,1]) # 2
print(a)
"""
[[1 2 3]
[4 5 6]
[7 8 9]]
"""
b=np.array([[0,2]])
c=np.array([[0,0]])
arr=a[b,c]
print(arr) # [[1 7]]
②
b=np.array([[x1,x2],[x1’,x2’]])
c=np.array([[y1,y2],[y1’,y2’]])
arr=a[b,c]
输出二维数组:[[x1,y1 x2,y2] [x1’,y1’ x2’,y2’]]
import numpy as np
a=np.array([[1,2,3],[4,5,6],[7,8,9]])
print(a[0,1]) # 2
print(a)
"""
[[1 2 3]
[4 5 6]
[7 8 9]]
"""
b=np.array([[0,2],[1,2]])
c=np.array([[0,0],[1,2]])
arr=a[b,c]
print(arr)
"""
[[1 7]
[5 9]]
"""
③
b=a[1:2,0:1]
1到2行,不含2
0到1列,不含1
import numpy as np
a=np.array([[1,2,3],[4,5,6],[7,8,9]])
print(a)
"""
[[1 2 3]
[4 5 6]
[7 8 9]]
"""
b=a[1:2,0:1]
print(b) # [[4]]
④
b=a[1:3,[1,2]]
行:1到3(不含)
列:第1和第2列(从0起)
import numpy as np
a=np.array([[1,2,3],[4,5,6],[7,8,9]])
print(a)
"""
[[1 2 3]
[4 5 6]
[7 8 9]]
"""
b=a[1:3,[1,2]]
print(b)
"""
[[5 6]
[8 9]]
"""
⑤
b=a[…,1:]
指明按列输出
输出第一列(从0起)往后的所有列
import numpy as np
a=np.array([[1,2,3],[4,5,6],[7,8,9]])
print(a)
"""
[[1 2 3]
[4 5 6]
[7 8 9]]
"""
b=a[...,1:]
print(b)
"""
[[2 3]
[5 6]
[8 9]]
"""
(2)布尔索引
a[a>5] 大于5的数
import numpy as np
a=np.array([[1,2,3],[4,5,6],[7,8,9]])
print(a[a>5]) # [6 7 8 9]
a[np.iscomplex(a)] 输出复数
import numpy as np
a=np.array([1,2,3+4j,5])
print(a) # [1.+0.j 2.+0.j 3.+4.j 5.+0.j]
print(a[np.iscomplex(a)]) # [3.+4.j]
(3)花式索引
a[[3,2]] 获取下标3和下标2对应的元素
import numpy as np
a=np.array([1,2,3,4,5])
b=a[[3,2]] # 下标3和下标2对应的元素
print(b) # [4 3]
print(b[0]) # 4
print(b[1]) # 3
二维数组
import numpy as np
a=np.array([[1,2,3],[4,5,6]])
print(a)
"""
[[1 2 3]
[4 5 6]]
"""
b=a[[1,0,0,1]] # 第1行,第0行,第0行,第1行
print(b)
"""
[[4 5 6]
[1 2 3]
[1 2 3]
[4 5 6]]
"""
倒序
import numpy as np
a=np.array([[1,2,3],[4,5,6]])
print(a)
"""
[[1 2 3]
[4 5 6]]
"""
b=a[[1,-1,0,-2]] # 第1行,倒数第一行,第0行,倒数第二行
print(b)
"""
[[4 5 6]
[4 5 6]
[1 2 3]
[1 2 3]]
"""
传入多个索引数组 ix_
a[np.ix_([1,3,0,2],[1,2])] 计算两组数的笛卡尔积(即全排列)
(第1行,第1列)的数; (第1行,第2列)的数
(3,1)(3,2)
(0,1)(0,2)
(2,1)(2,2)
import numpy as np
a=np.array([[1,2,3],[4,5,6],[7,8,9],[10,11,12]])
print(a)
"""
[[ 1 2 3]
[ 4 5 6]
[ 7 8 9]
[10 11 12]]
"""
b=a[np.ix_([1,3,0,2],[1,2])]
print(b)
"""
[[ 5 6]
[11 12]
[ 2 3]
[ 8 9]]
"""
四.迭代数组
1.按行访问
import numpy as np
a=np.arange(6).reshape(2,3)
print(a)
"""
[[0 1 2]
[3 4 5]]
"""
print(a[0]) # [0 1 2]
for x in a:
print(x)
"""
[0 1 2]
[3 4 5]
"""
2.按列访问:先转置
import numpy as np
a=np.arange(6).reshape(2,3)
print(a)
"""
[[0 1 2]
[3 4 5]]
"""
at=np.transpose(a) # 转置
print(at)
"""
[[0 3]
[1 4]
[2 5]]
"""
for x in at:
print(x)
"""
[0 3]
[1 4]
[2 5]
"""
3.按行迭代
使用nditer迭代,完成对数组中所有元素的访问
import numpy as np
a=np.arange(6).reshape(2,3)
print(a)
"""
[[0 1 2]
[3 4 5]]
"""
for x in np.nditer(a): # 迭代
print(x,end=" ") # 0 1 2 3 4 5
4.按列迭代
注:若先转置,再使用nditer,输出结果与转置前的结果相同,因为它们在内存中的存储顺序是一致的
import numpy as np
a=np.arange(6).reshape(2,3)
print(a)
"""
[[0 1 2]
[3 4 5]]
"""
at=np.transpose(a)
for x in np.nditer(a):
print(x,end=" ") # 0 1 2 3 4 5
通过查看内存地址可知,它们的内存地址是不同的,只是存储方式相同
import numpy as np
a=np.arange(6).reshape(2,3)
at=np.transpose(a)
print(id(a)) # 2014724773168
print(id(at)) # 2014999637776
因此,我们可以通过浅拷贝,将转置后的数组复制给新的变量。再输出时,就会得到按列迭代的结果
import numpy as np
a=np.arange(6).reshape(2,3)
print(a)
"""
[[0 1 2]
[3 4 5]]
"""
at=np.transpose(a)
print(at)
"""
[[0 3]
[1 4]
[2 5]]
"""
b=at.copy()
for x in np.nditer(b):
print(x,end=" ") # 0 3 1 4 2 5
当然,我们也可以通过order="F"的方式实现按列迭代
(order="C"表示按行迭代(默认))
import numpy as np
a=np.arange(6).reshape(2,3)
print(a)
for x in np.nditer(a,order="F"):
print(x,end=" ") # 0 3 1 4 2 5
5.迭代过程中数组元素的修改
x[…]=x* 2表示将数组中元素的值都变为原来的两倍,也可写为x*=2(对x两倍操作);但不能写为x=x*2,因为这样会视为定义新的同名变量x,对新变量的修改不会影响数组a,输出仍为1倍
此方式仅针对数组的迭代:for循环不仅是简单的遍历,更是一种迭代的思想。每次执行这些步骤时,都从变量的原值推出它的一个新值(即修改变量自身的值)
在迭代时,默认是只读类型。若要修改需要将op_flags改为readwrite或writeonly
import numpy as np
a=np.array([[1,2,3],[4,5,6]])
for x in np.nditer(a,op_flags=["readwrite"]):
x[...]=x*2 # 或 x*=2
print(a)
"""
[[ 2 4 6]
[ 8 10 12]]
"""
6.flags参数
import numpy as np
a = np.arange(0,20,2) # start stop(不含) step
a = a.reshape(2,5)
print(a)
"""
[[ 0 2 4 6 8]
[10 12 14 16 18]]
"""
for x in np.nditer(a):
print(x,end=" ") # 0 2 4 6 8 10 12 14 16 18
for x in np.nditer(a, flags = ["external_loop"]): # 输出为一位数组类型(默认按行输出)
print(x, end=" ") # [ 0 2 4 6 8 10 12 14 16 18]
for x in np.nditer(a, flags = ["external_loop"],order="F"): # F表示按列输出
print(x, end=" ") # [ 0 10] [ 2 12] [ 4 14] [ 6 16] [ 8 18]
五.广播
补:tile()方法
import numpy as np
a = np.array([1,2,3])
a=np.tile(a,2) # 对a按列复制2次
""""
[1 2 3 1 2 3]
"""
a = np.array([1,2,3])
a=np.tile(a,(2,1)) # 按行复制2次,按列复制1次(不变)
"""
[[1 2 3]
[1 2 3]]
"""
a = np.array([1,2,3])
a=np.tile(a,(2,2)) # 按行复制2次,按列复制2次
print(a)
"""
[[1 2 3 1 2 3]
[1 2 3 1 2 3]]
"""
对相同类型的数组计算,直接计算即可
import numpy as np
a=np.array([[1,2,3],[4,5,6]])
print(a)
"""
[[1 2 3]
[4 5 6]]
"""
b=np.array([[3,2,1],[1,2,3]])
print(b)
"""
[[3 2 1]
[1 2 3]]
"""
print(a+b) # 对应项相加
"""
[[4 4 4]
[5 7 9]]
"""
广播解决了不同形状数组的计算问题
import numpy as np
a = np.array([[ 0, 0, 0],
[10,10,10],
[20,20,20],
[30,30,30]])
b = np.array([0,1,2])
print(a + b)
"""
[[ 0 1 2]
[10 11 12]
[20 21 22]
[30 31 32]]
"""
以上过程是广播自动完成的,也可以tile方法手动完成
import numpy as np
a = np.array([[ 0, 0, 0],
[10,10,10],
[20,20,20],
[30,30,30]])
b = np.array([0,1,2])
c=np.tile(b,(4,1)) # 手动复制
print(a + b)
"""
[[ 0 1 2]
[10 11 12]
[20 21 22]
[30 31 32]]
"""
广播迭代
import numpy as np
a = np.arange(0,20,2) # start stop(不含) step
a = a.reshape(2,5)
print(a)
"""
[[ 0 2 4 6 8]
[10 12 14 16 18]]
"""
b = np.array([1,2,3,4,5])
for x,y in np.nditer([a,b]): # x从a中取,b从b中取
# 在迭代中,x会取遍a的值; b会通过广播补全,y从中依次取值
print (x,y)
"""
0 1
2 2
4 3
6 4
8 5
10 1
12 2
14 3
16 4
18 5
"""
六.数组操作
1.修改数组的形状
(1)reshape(arr,newshape,order)
arr待修改数组
newshape修改类型
order:C行、F列
import numpy as np
a=np.arange(12)
#使用b=a.reshape(3,4)也可
b=np.reshape(a,(3,4))
print(b)
"""
[[ 0 1 2 3]
[ 4 5 6 7]
[ 8 9 10 11]]
"""
b=np.reshape(a,(3,4),order="F") # 按列输出
print(b)
"""
[[ 0 3 6 9]
[ 1 4 7 10]
[ 2 5 8 11]]
"""
(2)flat
a.flat输出
import numpy as np
a=np.arange(12)
a=a.reshape(3,4)
for y in a: # 原形输出,a[0]为[0 1 2 3]
print(y)
"""
[0 1 2 3]
[4 5 6 7]
[8 9 10 11]
"""
for x in a.flat: # 输出数字
print(x,end=" ") # 0 1 2 3 4 5 6 7 8 9 10 11
(3)flatten
输出的都是一维数组,C(默认)表示按行输出,F表示按列输出
flatten返回的是数组的拷贝,对拷贝的修改不会影响原始数组
import numpy as np
a=np.arange(12).reshape(3,4)
print(a)
"""
[0 1 2 3]
[4 5 6 7]
[8 9 10 11]
"""
b=a.flatten()
print(b) # 按行输出:[ 0 1 2 3 4 5 6 7 8 9 10 11]
print(a.flatten(order="F")) # 按列输出:[ 0 4 8 1 5 9 2 6 10 3 7 11]
# 对b修改,不会影响原数组的值
b[2]=9
print(b) # [ 0 1 9 3 4 5 6 7 8 9 10 11]
print(a)
"""
[[ 0 1 2 3]
[ 4 5 6 7]
[ 8 9 10 11]]
"""
(4)ravel
功能与flatten类似,但ravel返回的是视图类型,对拷贝数组的修改会影响原数组
import numpy as np
a=np.arange(12).reshape(3,4)
print(a)
"""
[0 1 2 3]
[4 5 6 7]
[8 9 10 11]
"""
b=a.ravel()
print(b) # 行:[ 0 1 2 3 4 5 6 7 8 9 10 11]
print(a.ravel(order="F")) # 列:[ 0 4 8 1 5 9 2 6 10 3 7 11]
b[2]=9
print(b) # [ 0 1 9 3 4 5 6 7 8 9 10 11]
print(a)
"""
[[ 0 1 9 3]
[ 4 5 6 7]
[ 8 9 10 11]]
"""
2.翻转数组(转置)
import numpy as np
a=np.arange(12).reshape(3,4)
print(a)
"""
[0 1 2 3]
[4 5 6 7]
[8 9 10 11]
"""
# 以下三条语句均可
print(a.T)
print(a.transpose())
print(np.transpose(a))
"""
[[ 0 4 8]
[ 1 5 9]
[ 2 6 10]
[ 3 7 11]]
"""
(1)三维数组
如下是一个三维数组
import numpy as np
a=np.arange(8).reshape(2,2,2)
print(a)
"""
[[[0 1]
[2 3]]
[[4 5]
[6 7]]]
"""
可以通过a[0]可以指明第一块数据,通过a[1]可以指明第二块数据
print(a[0])
"""
[[0 1]
[2 3]]
"""
在选择完块后即可按照(行,列)的方式在该块选择指定元素
# 第0块的第1行的第0列元素
print(a[0][1][0]) # 2
因此,该数组的所有元素可表示为
a[0,0,0]=0
a[0,0,1]=1
a[0,1,0]=2
a[0,1,1]=3
a[1,0,0]=4
a[1,0,1]=5
a[1,1,0]=6
a[1,1,1]=7
# a数组
[[[0 1]
[2 3]]
[[4 5]
[6 7]]]
可参照此图的三维坐标系,将三个参数 [x,y,z] 依次视为三个轴,对应序号0,1,2
(2)rollaxis(arr,axis,start)
arr表示待处理数组
axis轴必须放在start轴的前面一格(start轴默认为0号)。若不在,需要进行滚动。
如
(axis,start)=(2,0) 表示2号轴必须滚动到0号轴的前面一格(向前滚动类似于直接插入排序的元素移动),其余元素保持不变
绿色移动让出位置,红色插入
变为
再如
(axis,start)=(1,4) 表示1号轴必须滚动到4号轴的前面一格(向后滚动类似于逆向的直接插入排序的元素移动),其余元素保持不变
变为
[例1]
import numpy as np
a=np.arange(8).reshape(2,2,2)
print(a)
"""输出
[[[0 1]
[2 3]]
[[4 5]
[6 7]]]
"""
print(np.rollaxis(a,2)) # 2号轴放到0号轴前
# [x,y,z]变为[z,x,y]
"""输出(过程见下文)
[[[0 2]
[4 6]]
[[1 3]
[5 7]]]
"""
变为
通过[x,y,z]→[z,x,y] 得:
a[0,0,0]=0→a[0,0,0] (将原来放在a[0,0,0]位置的0放在a[0,0,0]处)
a[0,0,1]=1→a[1,0,0] (将原来放在a[0,0,1]位置的1放在a[1,0,0]处)
a[0,1,0]=2→a[0,0,1] (将原来放在a[0,1,0]位置的2放在a[0,0,1]处)
a[0,1,1]=3→a[1,0,1] (将原来放在a[0,1,1]位置的3放在a[1,0,1]处)
a[1,0,0]=4→a[0,1,0] …
a[1,0,1]=5→a[1,1,0]
a[1,1,0]=6→a[0,1,1]
a[1,1,1]=7→a[1,1,1]
[例2]
import numpy as np
a=np.arange(8).reshape(2,2,2)
print(a)
"""输出
[[[0 1]
[2 3]]
[[4 5]
[6 7]]]
"""
b=np.rollaxis(a,0,2) # 0号轴放到2号轴前面
print(b)
"""输出
[[[0 1]
[4 5]]
[[2 3]
[6 7]]]
"""
变为
a[0,0,0]=0→a[0,0,0] (将0放在a[0,0,0]位置)
a[0,0,1]=1→a[0,0,1] (将1放在a[0,0,1]位置)
a[0,1,0]=2→a[1,0,0] (将2放在a[1,0,0]位置)
a[0,1,1]=3→a[1,0,1]
a[1,0,0]=4→a[0,1,0]
a[1,0,1]=5→a[0,1,1]
a[1,1,0]=6→a[1,1,0]
a[1,1,1]=7→a[1,1,1]
[例3]
import numpy as np
a=np.arange(32).reshape(2,2,2,2,2) # 5维数组
b=np.rollaxis(a,1,4) # 1号轴放到4号轴前面
print(b)
"""输出
[[[[[ 0 1]
[ 8 9]]
[[ 2 3]
[10 11]]]
[[[ 4 5]
[12 13]]
[[ 6 7]
[14 15]]]]
[[[[16 17]
[24 25]]
[[18 19]
[26 27]]]
[[[20 21]
[28 29]]
[[22 23]
[30 31]]]]]
"""
变为
注意,因为axis要放到start前面一个,也就是start-1,对于5维数组(0~4),start可以为5(不会越界),这样只需将axis滚动到最后即可
例如 np.rollaxis(a,1,5)
变为
(3)swapaxes
swapaxes(arr,axis1,axis2)
交换axis1轴和axis2轴
axis2不可省略
import numpy as np
a=np.arange(8).reshape(2,2,2)
print(a)
"""输出
[[[0 1]
[2 3]]
[[4 5]
[6 7]]]
"""
print(np.swapaxes(a,2,0)) # 2号轴和0号轴互换
# [x,y,z]变为[z,y,x]
"""输出
[[[0 4]
[2 6]]
[[1 5]
[3 7]]]
"""
a[0,0,0]=0→a[0,0,0] (将0放在a[0,0,0]位置)
a[0,0,1]=1→a[1,0,0] (将1放在a[1,0,0]位置)
a[0,1,0]=2→a[0,1,0] (将2放在a[0,1,0]位置)
a[0,1,1]=3→a[1,1,0]
a[1,0,0]=4→a[0,0,1]
a[1,0,1]=5→a[1,0,1]
a[1,1,0]=6→a[0,1,1]
a[1,1,1]=7→a[1,1,1]
(4)查看元素位置
np.where(b==4) 查看b数组的4号元素位置[1,0,0]
import numpy as np
a=np.arange(8).reshape(2,2,2)
print(a)
"""输出
[[[0 1]
[2 3]]
[[4 5]
[6 7]]]
"""
print(np.where(a==4)) # (array([1], dtype=int64), array([0], dtype=int64), array([0], dtype=int64))
b=np.swapaxes(a,2,0)
print(np.where(b==4)) # (array([0], dtype=int64), array([0], dtype=int64), array([1], dtype=int64))
print(b)
"""输出
[[[0 4]
[2 6]]
[[1 5]
[3 7]]]
"""
3.修改数组维度
(1)numpy.broadcast
先来回顾一下上文提到的广播迭代
import numpy as np
a = np.arange(0,20,2) # start stop(不含) step
a = a.reshape(2,5)
print(a)
"""
[[ 0 2 4 6 8]
[10 12 14 16 18]]
"""
b = np.array([1,2,3,4,5])
for x,y in np.nditer([a,b]): # x从a中取,b从b中取
# 在迭代中,x会取遍a的值; b会通过广播补全,y从中依次取值
print (x,y)
"""
0 1
2 2
4 3
6 4
8 5
10 1
12 2
14 3
16 4
18 5
"""
在广播迭代中,x代表行,y代表列,在迭代过程中可以分别输出。numpy.broadcast与之不同的是,生成的结果是元组形式,只需要用一个变量来表示
import numpy as np
a = np.arange(0,20,2) # start stop(不含) step
a = a.reshape(2,5)
print(a)
"""
[[ 0 2 4 6 8]
[10 12 14 16 18]]
"""
b = np.array([1,2,3,4,5])
print(b) # [1 2 3 4 5]
t=np.broadcast(a,b)
for x in t:
print(x)
"""
(0, 1)
(2, 2)
(4, 3)
(6, 4)
(8, 5)
(10, 1)
(12, 2)
(14, 3)
(16, 4)
(18, 5)
"""
当然我们也可以将其拆为行和列。如下例就与广播迭代中print(x)的效果相同
import numpy as np
a = np.arange(0,20,2) # start stop(不含) step
a = a.reshape(2,5)
print(a)
"""
[[ 0 2 4 6 8]
[10 12 14 16 18]]
"""
b = np.array([1,2,3,4,5])
print(b) # [1 2 3 4 5]
t=np.broadcast(a,b)
hang,lie=t.iters
for x in hang:
print(x)
"""
0
2
4
6
8
10
12
14
16
18
"""
可以通过shape返回广播对象的形状
广播是一个补齐的过程,不能说广播结果的形状一定与大的相同。例如一个3×1的数组(向右补齐)和一个1×3的数组(向下补齐),广播后变为3×3
import numpy as np
a = np.arange(0,20,2) # start stop(不含) step
a = a.reshape(2,5)
print(a)
"""
[[ 0 2 4 6 8]
[10 12 14 16 18]]
"""
b = np.array([1,2,3,4,5])
print(b) # [1 2 3 4 5]
t=np.broadcast(a,b)
print(t.shape) # (2, 5)
(2)numpy.broadcast_to
一维行向量只能广播行
一维列向量只能广播列
多位向量只能广播自身(无意义)
import numpy as np
a = np.arange(0,10,2) # start stop(不含) step
a = a.reshape(1,5)
print(a) # [[0 2 4 6 8]]
print(np.broadcast_to(a,(3,5))) # 3行5列
"""
[[0 2 4 6 8]
[0 2 4 6 8]
[0 2 4 6 8]]
"""
print(np.broadcast_to(a,(3,2,5))) # 3块2行5列
"""
[[[0 2 4 6 8]
[0 2 4 6 8]]
[[0 2 4 6 8]
[0 2 4 6 8]]
[[0 2 4 6 8]
[0 2 4 6 8]]]
"""
(3)numpy.expand_dims
增加axis指定的轴
import numpy as np
a=np.array([[1,2,3],[4,5,6]])
print(a.shape) # (2, 3)
print(a)
"""
[[1 2 3]
[4 5 6]]
"""
a[0,0]=1
a[0,1]=2
a[0,2]=3
a[1,0]=4
a[1,1]=5
a[1,2]=6
①当axis=0时
b=np.expand_dims(a,axis=0) # axis=0表示在0号位(x号位)插入轴
print(b.shape) # (1, 2, 3) 变为1块2行3列
print(b)
"""
[[[1 2 3]
[4 5 6]]]
"""
修改后,第一个参数指明所在的是x号块,每个元素所在的行列均不变,维度由二维变为3维
a[x,0,0]=1
a[x,0,1]=2
a[x,0,2]=3
a[x,1,0]=4
a[x,1,1]=5
a[x,1,2]=6
②当axis=1时
import numpy as np
a=np.array([[1,2,3],[4,5,6]])
print(a.shape) # (2, 3)
print(a)
"""
[[1 2 3]
[4 5 6]]
"""
c=np.expand_dims(a,axis=1) # 在1号位(y)插入轴
print(c.shape) # (2, 3, 1) c的形状为2块3行1列
print(c)
"""
[[[1 2 3]]
[[4 5 6]]]
"""
a[0,y,0]=1
a[0,y,1]=2
a[0,y,2]=3
a[1,y,0]=4
a[1,y,1]=5
a[1,y,2]=6
可以看出,数组被分为了2块,例如元素4在第1块的第0列
③当axis=2时
import numpy as np
a=np.array([[1,2,3],[4,5,6]])
print(a.shape) # (2, 3)
print(a)
"""
[[1 2 3]
[4 5 6]]
"""
d=np.expand_dims(a,axis=2) # 在2号位(z)插入轴
print(d.shape) # (2, 3, 1)
print(d)
"""
[[[1]
[2]
[3]]
[[4]
[5]
[6]]]
"""
a[0,0,z]=1
a[0,1,z]=2
a[0,2,z]=3
a[1,0,z]=4
a[1,1,z]=5
a[1,2,z]=6
数组被分为2块,例如元素4,在第一块的第0行
(4)numpy.squeeze
删除axis指定的轴
①axis=0(默认)
删除轴0,即删除表示块的参数,1块2行3列变为2行三列
import numpy as np
a=np.array([[[1 ,2 ,3],[4 ,5 ,6]]])
print(a.shape) # (1, 2, 3)
print(a)
"""
[[[1 2 3]
[4 5 6]]]
"""
b=np.squeeze(a,axis=0) # 删除轴0
print(b.shape) # (2, 3)
print(b)
"""
[[1 2 3]
[4 5 6]]
"""
②axis=1
2块1行3列,删除y,变为2行3列
import numpy as np
a=np.array([[1,2,3],[4,5,6]]).reshape(2,1,3)
print(a.shape) # (2, 1, 3)
print(a)
"""
[[[1 2 3]]
[[4 5 6]]]
"""
b=np.squeeze(a,axis=1) # 删除轴1
print(b.shape) # (2, 3)
print(b)
"""
[[1 2 3]
[4 5 6]]
"""
③axis=2
2块3行1列,删除z,变为2行3列
import numpy as np
a=np.array([[1,2,3],[4,5,6]]).reshape(2,3,1)
print(a.shape) # (2, 3, 1)
print(a)
"""
[[[1]
[2]
[3]]
[[4]
[5]
[6]]]
"""
b=np.squeeze(a,axis=2) # 删除轴2
print(b.shape) # (2, 3)
print(b)
"""
[[1 2 3]
[4 5 6]]
"""
4.连接数组
(1)concatenate
可以连接多个数组
axis=0竖直连接(默认)
axis=1水平连接
import numpy as np
a=np.array([[1,2],[3,4]])
print(a)
"""
[[1 2]
[3 4]]
"""
b=np.array([[5,6],[7,8]])
print(b)
"""
[[5 6]
[7 8]]
"""
print(np.concatenate((a,b),axis=0)) # 竖直连接
"""
[[1 2]
[3 4]
[5 6]
[7 8]]
"""
import numpy as np
a=np.array([[1,2],[3,4]])
print(a)
"""
[[1 2]
[3 4]]
"""
b=np.array([[5,6],[7,8]])
print(b)
"""
[[5 6]
[7 8]]
"""
print(np.concatenate((a,b),axis=1)) # 水平连接
"""
[[1 2 5 6]
[3 4 7 8]]
"""
(2)stack
垂直堆叠,结果会分块
axis=0 整体堆叠(默认)
axis=1 按行堆叠
axis=2 按行转置堆叠
import numpy as np
a=np.array([[1,2,3],[4,5,6],[7,8,9]])
print(a)
"""
[[1 2 3]
[4 5 6]
[7 8 9]]
"""
b=np.array([[10,11,12],[13,14,15],[16,17,18]])
print(b)
"""
[[10 11 12]
[13 14 15]
[16 17 18]]
"""
print(np.stack((a,b),axis=0)) # 按块竖直堆叠
"""
[[[ 1 2 3]
[ 4 5 6]
[ 7 8 9]]
[[10 11 12]
[13 14 15]
[16 17 18]]]
"""
import numpy as np
a=np.array([[1,2,3],[4,5,6],[7,8,9]])
print(a)
"""
[[1 2 3]
[4 5 6]
[7 8 9]]
"""
b=np.array([[10,11,12],[13,14,15],[16,17,18]])
print(b)
"""
[[10 11 12]
[13 14 15]
[16 17 18]]
"""
print(np.stack((a,b),axis=1)) # 按行堆叠,一人一行
"""
[[[ 1 2 3]
[10 11 12]]
[[ 4 5 6]
[13 14 15]]
[[ 7 8 9]
[16 17 18]]]
"""
import numpy as np
a=np.array([[1,2,3],[4,5,6],[7,8,9]])
print(a)
"""
[[1 2 3]
[4 5 6]
[7 8 9]]
"""
b=np.array([[10,11,12],[13,14,15],[16,17,18]])
print(b)
"""
[[10 11 12]
[13 14 15]
[16 17 18]]
"""
print(np.stack((a,b),axis=2)) # 行转置堆叠,一人一列
"""
[[[ 1 10]
[ 2 11]
[ 3 12]]
[[ 4 13]
[ 5 14]
[ 6 15]]
[[ 7 16]
[ 8 17]
[ 9 18]]]
"""
(3)hstack
水平堆叠,结果不分块,没有axis参数
import numpy as np
import numpy as np
a=np.array([[1,2,3],[4,5,6],[7,8,9]])
print(a)
"""
[[1 2 3]
[4 5 6]
[7 8 9]]
"""
b=np.array([[10,11,12],[13,14,15],[16,17,18]])
print(b)
"""
[[10 11 12]
[13 14 15]
[16 17 18]]
"""
print(np.hstack((a,b)))
"""
[[ 1 2 3 10 11 12]
[ 4 5 6 13 14 15]
[ 7 8 9 16 17 18]]
"""
(4)vstack
垂直堆叠,结果不分块,没有axis参数
import numpy as np
import numpy as np
a=np.array([[1,2,3],[4,5,6],[7,8,9]])
print(a)
"""
[[1 2 3]
[4 5 6]
[7 8 9]]
"""
b=np.array([[10,11,12],[13,14,15],[16,17,18]])
print(b)
"""
[[10 11 12]
[13 14 15]
[16 17 18]]
"""
print(np.vstack((a,b)))
"""
[[ 1 2 3]
[ 4 5 6]
[ 7 8 9]
[10 11 12]
[13 14 15]
[16 17 18]]
"""
5.分割数组
(1)split(数组,切割方式,行/列)
import numpy as np
a=np.array([[1,2,3],[4,5,6],[7,8,9]])
print(a)
"""
[[1 2 3]
[4 5 6]
[7 8 9]]
"""
print(np.split(a,3,axis=0))
"""axis=0按行切分(默认),切成3组
[array([[1, 2, 3]]), array([[4, 5, 6]]), array([[7, 8, 9]])]
"""
print(np.split(a,3,axis=1))
"""axis=1按列切分,切成3组
[array([[1],
[4],
[7]]), array([[2],
[5],
[8]]), array([[3],
[6],
[9]])]
"""
指明切的范围
import numpy as np
a=np.array([[1,2,3,4,5],[6,7,8,9,10],[11,12,13,14,15]])
print(a)
"""
[[ 1 2 3 4 5]
[ 6 7 8 9 10]
[11 12 13 14 15]]
"""
print(np.split(a,[1,4],axis=1))
"""在1号位切一刀,在3号位切一刀(4不含),axis=1垂直切,切的内容保留在一个数组中
[array([[ 1],
[ 6],
[11]]), array([[ 2, 3, 4],
[ 7, 8, 9],
[12, 13, 14]]), array([[ 5],
[10],
[15]])]
"""
图解
(2)hsplit
垂直切割,指明切割组数,切割结果必须是相同形状,没有axis参数
import numpy as np
a=np.array([[1,2,3,4],[6,7,8,9],[11,12,13,14]])
print(a)
"""
[[ 1 2 3 4]
[ 6 7 8 9]
[11 12 13 14]]
"""
print(np.hsplit(a,2))
"""垂直切,分为2组
[array([[ 1, 2],
[ 6, 7],
[11, 12]]), array([[ 3, 4],
[ 8, 9],
[13, 14]])]
"""
(3)vsplit
水平切割,指明切割组数,切割结果必须是相同形状,没有axis参数
import numpy as np
a=np.array([[1,2,3],[4,5,6],[7,8,9],[10,11,12]])
print(a)
"""
[[ 1 2 3]
[ 4 5 6]
[ 7 8 9]
[10 11 12]]
"""
print(np.vsplit(a,2))
"""水平切,分为2组
[array([[1, 2, 3],
[4, 5, 6]]), array([[ 7, 8, 9],
[10, 11, 12]])]
"""
6.数组元素的添加与删除
(1)append
axis=None(默认):生成一维数组,末尾添加
axis=0:垂直添加(列数要相同)
axis=1:水平添加(行数要相同)
import numpy as np
a=np.array([[1,2,3],[4,5,6]])
print(a)
"""
[[1 2 3]
[4 5 6]]
"""
print(np.append(a,[[7,8,9]],axis=None)) # [1 2 3 4 5 6 7 8 9]
print(np.append(a,[[7,8,9]],axis=0))
"""
[[1 2 3]
[4 5 6]
[7 8 9]]
"""
print(np.append(a,[[7,8,9],[10,11,12]],axis=1))
"""
[[ 1 2 3 7 8 9]
[ 4 5 6 10 11 12]]
"""
(2)insert
insert(数组,插入位置,插入元素,axis)
axis=None(默认):先展开,再指定位置插入元素,结果为一维数组
axis=0:垂直添加(只有一个插入元素时不会异常)
axis=1:水平添加(只有一个插入元素时不会异常)
import numpy as np
a=np.array([[1,2,3],[4,5,6],[7,8,9]])
print(a)
"""
[[1 2 3]
[4 5 6]
[7 8 9]]
"""
print(np.insert(a,2,7)) # [1 2 7 3 4 5 6 7 8 9] 先展开,在第2个位置插入7
print(np.insert(a,2,[7,8])) # [1 2 7 8 3 4 5 6 7 8 9] 先展开,在第2个位置插入7,8
print(np.insert(a,1,7,axis=0)) # axis=0表示垂直插入,在1号位插入7 7 7
"""
[[1 2 3]
[7 7 7]
[4 5 6]
[7 8 9]]
"""
print(np.insert(a,2,[9,8,5],axis=0))
"""
[[1 2 3]
[4 5 6]
[9 8 5]
[7 8 9]]
"""
print(np.insert(a,2,[9,8,5],axis=1)) # axis=1表示水平方向插入,在2号位插入 [[9],[8],[5]]
"""
[[1 2 9 3]
[4 5 8 6]
[7 8 5 9]]
"""
print(np.insert(a,2,[7,8],axis=0)) # ValueError [7,8]无法补齐
(3)delete
delete(数组,删除位置,axis)
axis=None(默认):先展开,再删除指定位置的元素
axis=0:删除指定的水平方向的一行
axis=1:删除指定的竖直方向的一列
import numpy as np
a=np.array([[1,2,3],[4,5,6],[7,8,9]])
print(a)
"""
[[1 2 3]
[4 5 6]
[7 8 9]]
"""
print(np.delete(a,5,axis=None)) # [1 2 3 4 5 7 8 9] 先展开,删除第5个
print(np.delete(a,[5,6],axis=None)) # [1 2 3 4 5 8 9] 先展开,删除第5个和第6个
print(np.delete(a,1,axis=0)) # 删除第一行
"""
[[1 2 3]
[7 8 9]]
"""
print(np.delete(a,1,axis=1)) # 删除第一列
"""
[[1 3]
[4 6]
[7 9]]
"""
print(np.delete(a,[0,1],axis=1)) # 删除第0列和第1列
"""
[[3]
[6]
[9]]
"""
(4)unique
删除数组或列表的重复元素,生成结果列表
unique(arr,return_index,return_inverse,return_counts)
return_index:返回新列表各元素在原数组的下标
return_inverse:返回原数组各元素在新列表的下标
return_counts:返回新列表各元素在原数组中的出现次数
import numpy as np
a=np.array([[1,2,3],[2,3,6],[2,8,2]])
print(a)
"""
[[1 2 3]
[2 3 6]
[2 8 2]]
"""
print(np.unique(a)) # [1 2 3 6 8] 删除重复元素,一维数组输出
print(np.unique(a,return_index=True)) # 返回每个新数组元素在原数组(一维展开)中首次出现的下标
"""
原数组展开:[1,2,3,2,3,6,2,8,2]
说明:输出为12368,其中1对应0号位,2对应1号为,3对应2号位,6对应5号位,8对应7号位
输出:(array([1, 2, 3, 6, 8]), array([0, 1, 2, 5, 7], dtype=int64))
"""
print(np.unique(a,return_inverse=True)) # 返回原数组元素在新列表中的下标
"""
新列表元素12368对应下标01234,原数组展开为[1,2,3,2,3,6,2,8,2],对应下标依次为012123141
输出:(array([1, 2, 3, 6, 8]), array([0, 1, 2, 1, 2, 3, 1, 4, 1], dtype=int64))
"""
print(np.unique(a,return_counts=True)) # 返回新列表中元素在原数组中出现的次数
"""
原数组展开为[1,2,3,2,3,6,2,8,2],例如新列表中的2出现次数为4
输出:(array([1, 2, 3, 6, 8]), array([1, 4, 2, 1, 1], dtype=int64))
"""
七.位运算
使用bin可输出0b开头的二进制数
a=8
print(bin(a)) # 0b1000
使用binary_repr可直接输出二进制并指定位数
import numpy as np
a=13
print(np.binary_repr(a,width=8)) # 00001101
# 负数以补码存储
b=-13
print(np.binary_repr(b,width=8)) # 11110011
1.bitwise_and
按位与:将两个数的二进制相与,得到二进制,转化为十进制输出
import numpy as np
a,b=16,17
print(bin(a),bin(b)) # 0b10000 0b10001
print(np.bitwise_and(a,b)) # a和b按位与,结果为10000,输出16
2.bitwise_or
按位或:将两个数的二进制相或,得到二进制,转化为十进制输出
import numpy as np
a,b=16,17
print(bin(a),bin(b)) # 0b10000 0b10001
print(np.bitwise_or(a,b)) # a和b按位与,结果为10001,输出17
3.invert
对整数按位取反
关于按位取反、左移、右移的计算过程见“1-python基础 -6.运算符 -(5)逻辑运算”,下面只给出代码形式
import numpy as np
a=13
print(bin(a)) # 0b1101
print(np.invert(a)) # -14
import numpy as np
a=-13
print(bin(a)) # -0b1101
print(np.invert(a)) # 12
4.left_shift
left_shift(待移动元素,移动位数)
左移:高位丢弃,低位补0
import numpy as np
a=13
print(bin(a)) # 0b1101
print(np.left_shift(a,2)) # 52
b=-13
print(bin(b)) # -0b1101
print(np.left_shift(b,2)) # -52
5.right_shift
右移:负数补1[补码],正数补0
import numpy as np
a=13
print(bin(a)) # 0b1101
print(np.right_shift(a,2)) # 3
b=-13
print(bin(b)) # -0b1101
print(np.right_shift(b,2)) # -4
八.函数
(一)字符串函数
1.char.add
连接两个字符串
import numpy as np
print(np.char.add("hello"," jack")) # hello jack
print(np.char.add(["hello","hi"],[" one"," two"])) # ['hello one' 'hi two']
2.char.multiply
复制n次
import numpy as np
print(np.char.multiply("hello ",3)) # hello hello hello
3.char.center
左右填充fillchar,第二个参数表示输出总长度
import numpy as np
print(np.char.center("hello",20,fillchar="$")) # $$$$$$$hello$$$$$$$$
4.char.capitalize
首字母转大写
import numpy as np
print(np.char.capitalize("hello")) # Hello
5.char.title
每个单词的首字母转大写
import numpy as np
print(np.char.title("hello jack")) # Hello Jack
6.char.lower
转为全小写
import numpy as np
print(np.char.lower("hELlo JaCK")) # hello jack
7.char.upper
转为全大写
import numpy as np
print(np.char.upper("hELlo JaCK")) # HELLO JACK
8.char.split
默认以字符分割
import numpy as np
print(np.char.split("hELlo JaCK")) # ['hELlo', 'JaCK']
print(np.char.split("hEL,lo JaCK",sep=",")) # ['hEL', 'lo JaCK']
9.char.splitlines
使用\n \r \r\n来分割字符串
import numpy as np
print(np.char.splitlines("hE\nLlo Ja\rCK,hah\r\naha")) # ['hE', 'Llo Ja', 'CK,hah', 'aha']
10.char.strip
移除开头和结尾的特定内容(默认为空格和换行)
import numpy as np
print(np.char.strip("\nhELlo JaCK,hahaha ")) #输出:hELlo JaCK,hahaha
print(np.char.strip(" hELlo JaCK,hahaha ")) #输出:hELlo JaCK,hahaha
print(np.char.strip("aaahELlo JaCK,hahahaaa","a")) #输出:hELlo JaCK,hahah
print(np.char.strip(["aaahELlo","aalala"],"a")) #输出:['hELlo' 'lal']
11.char.join
import numpy as np
print(np.char.join("-","nihao")) # n-i-h-a-o
print(np.char.join(["-","="],["hello","jack"])) # ['h-e-l-l-o' 'j=a=c=k']
12.char.replace
import numpy as np
print(np.char.replace("hekko","kk","ll")) # hello
# kk替换为ll
13.char.encode/decode
encode编码
decode解码
import numpy as np
a=np.char.encode("hello","cp500") # 编码方式cp500
print(a) # b'\x88\x85\x93\x93\x96'
print(np.char.decode(a,"cp500")) # hello
import numpy as np
a=np.char.encode("hello") # 默认编码utf-8
print(a) # b'hello'
print(np.char.decode(a)) # hello
(二)数学函数
1.三角函数
必须转换为弧度制计算
角度转弧度:角度×π/180
(1)sin
可以用np.pi表示π的值
sin30°可写为 30°×π/180 或π/6
import numpy as np
print(np.pi) # 直接输出π的值:3.141592653589793
print(np.sin(30*np.pi/180)) # 0.49999999999999994
print(np.sin(np.pi/6)) # 0.49999999999999994
可以使用sympy控制精度(sympy没有arc)
import sympy as sy
print(sy.pi) # π不会直接以值的形式输出,输出:pi
print(sy.sin(sy.pi/6)) # 1/2
下文随机使用sy和np
(2)cos、tan、arcsin、arccos、arctan
弧度转角度:弧度×180/π
或者使用degrees()函数
import numpy as np
import sympy as sy
print(sy.cos(60*sy.pi/180)) # 1/2
print(sy.tan(45*sy.pi/180)) # 1
print(np.arcsin(1/2)) # 弧度制输出:0.5235987755982989
print(np.arcsin(1/2)*180/np.pi) # 转角度方法一:30.000000000000004
print(np.degrees(np.arcsin(1/2))) # 转角度方法二:30.000000000000004
print(np.arccos(1/2)*180/np.pi) # 60.00000000000001
print(np.arctan(1)*180/np.pi) # 45.0
(3)数组批量转换
import numpy as np
a=np.array([30,60,90])
print(np.sin(a*np.pi/180)) # [0.5 0.8660254 1. ]
2.舍入函数
(1)around
decimals=0(默认):对小数点后第一位四舍五入,只保留到小数点后1位且该位一定为0
decimals=n表示保留到小数点后n位,四舍五入
decimals=-n表示对小数点前第n位四舍五入,该位及其往右均为0
around同样可以使用数组批量处理
import numpy as np
print(np.around(1.43)) # 1.0
print(np.around(1.56)) # 2.0
print(np.around(1.567,decimals=1)) # 1.6
print(np.around(1.567,decimals=2)) # 1.57
print(np.around(2.567,decimals=-1)) # 0.0
print(np.around(5.567,decimals=-1)) # 10.0
print(np.around(24.567,decimals=-1)) # 20.0
print(np.around(25.567,decimals=-1)) # 30.0
print(np.around(255.567,decimals=-2)) # 300.0
(2)floor
floor(x)相当于 输出取整函数[x],输出结果为不超过x的最大整数
import numpy as np
print(np.floor(1.5)) # 1.0
print(np.floor(2)) # 2.0
print(np.floor(-2)) # -2.0
print(np.floor(-2.5)) # -3.0
print(np.floor(-2.4)) # -3.0
a=np.array([1.2,1.8])
print(np.floor(a)) # [1. 1.]
(3)ceil
向上取整,floor(x) 的输出结果为不小于x的最大整数
import numpy as np
print(np.ceil(1.5)) # 2.0
print(np.ceil(2)) # 2.0
print(np.ceil(-2)) # -2.0
print(np.ceil(-2.5)) # -2.0
print(np.ceil(-2.4)) # -2.0
a=np.array([1.2,1.8])
print(np.ceil(a)) # [2. 2.]
(三)算术函数
1.add
加法操作,数组必须满足广播规则
import numpy as np
a=np.array([[1,2,3],[4,5,6]])
print(a)
"""
[[1 2 3]
[4 5 6]]
"""
b=np.array([1,2,3])
"""
[1 2 3]
"""
print(b)
print(a+b) # 输出如下
print(np.add(a,b)) # 输出如下
"""
[[2 4 6]
[5 7 9]]
"""
2.subtract
减
import numpy as np
a=np.array([[1,2,3],[4,5,6]])
print(a)
"""
[[1 2 3]
[4 5 6]]
"""
b=np.array([1,2,3])
"""
[1 2 3]
"""
print(b)
print(a-b) # 输出如下
print(np.subtract(a,b)) # 输出如下
"""
[[0 0 0]
[3 3 3]]
"""
3.multiply
乘
import numpy as np
a=np.array([[1,2,3],[4,5,6]])
print(a)
"""
[[1 2 3]
[4 5 6]]
"""
b=np.array([1,2,3])
"""
[1 2 3]
"""
print(b)
print(a*b) # 输出如下
print(np.multiply(a,b)) # 输出如下
"""
[[ 1 4 9]
[ 4 10 18]]
"""
4.divide
除
import numpy as np
a=np.array([[1,2,3],[4,5,6]])
print(a)
"""
[[1 2 3]
[4 5 6]]
"""
b=np.array([1,2,3])
"""
[1 2 3]
"""
print(b)
print(a/b) # 输出如下
print(np.divide(a,b)) # 输出如下
"""
[[1. 1. 1. ]
[4. 2.5 2. ]]
"""
### 5.reciprocal
返回每个元素的倒数
import numpy as np
a=np.array([[1,2,3],[4,5,6]],dtype="float")
print(a)
"""
[[1 2 3]
[4 5 6]]
"""
print(np.reciprocal(a))
"""
[[1. 0.5 0.33333333]
[0.25 0.2 0.16666667]]
"""
6.power
power(a,n)表示an
import numpy as np
a=np.array([[1,2,3],[4,5,6]],dtype="float")
print(a)
"""
[[1 2 3]
[4 5 6]]
"""
print(np.power(a,2))
"""
[[ 1. 4. 9.]
[16. 25. 36.]]
"""
n也可以是数组(按广播规则)
import numpy as np
a=np.array([[1,2,3],[4,5,6]],dtype="float")
print(a)
"""
[[1 2 3]
[4 5 6]]
"""
n=np.array([1,2,3])
print(np.power(a,n))
"""
[[ 1. 4. 27.]
[ 4. 25. 216.]]
"""
7.mod
模除,计算余数
import numpy as np
a=np.array([[1,2,3],[4,5,6]],dtype="float")
print(a)
"""
[[1 2 3]
[4 5 6]]
"""
print(np.mod(a,2))
"""
[[1. 0. 1.]
[0. 1. 0.]]
"""
b=np.array([3,2,1])
print(np.mod(a,b))
"""
[[1. 0. 0.]
[1. 1. 0.]]
"""
(四)统计函数
1.amin/amax
沿axis轴方向找最值
axis=0表示沿横轴,即找每一列的最值
amin
import numpy as np
a=np.arange(12).reshape(3,4)
print(a)
"""
[[ 0 1 2 3]
[ 4 5 6 7]
[ 8 9 10 11]]
"""
print(np.amin(a,axis=0)) # [0 1 2 3]
print(np.amin(a,1)) # [0 4 8]
amax
import numpy as np
a=np.arange(12).reshape(3,4)
print(a)
"""
[[ 0 1 2 3]
[ 4 5 6 7]
[ 8 9 10 11]]
"""
print(np.amax(a,axis=0)) # [ 8 9 10 11]
print(np.amax(a,1)) # [ 3 7 11]
2.ptp
ptp=max-min
axis=0:沿0轴
axis=1:沿1轴
不写:整个数组的最大-最小
import numpy as np
a=np.arange(12).reshape(3,4)
print(a)
"""
[[ 0 1 2 3]
[ 4 5 6 7]
[ 8 9 10 11]]
"""
print(np.ptp(a,axis=0)) # [8 8 8 8]
print(np.ptp(a,axis=1)) # [3 3 3]
print(np.ptp(a)) # 11
3.percentile
百分位数
percentile(a,q,axis)
q表示百分比,取值为0~100
先对数组进行排序(由小到大)
q=0表示第一个数
q=100表示最后一个数
q=50表示中位数(中间的数/中间两个数的均值)
q=其他时,计算方式如下
用n表示数组中的元素个数
a’[k]表示排序后的a数组,k为下标索引
令 q/[100/(n-1)] =t
则 percentile(a,q)=a’[ ⌊t⌋ ] +(a’[ ⌊t⌋+1 ]-a’[ ⌊t⌋ ]) * (t-⌊t⌋)
例如:
a数组排序后为 1 7 9 12 23 54
n=6,共有n-1=5间隔
100/5=20,表示每个间隔占比20%
若q=25%,25/20=1.25表示从起点往后1.25个间隔
也就是a[1]+0.25个间隔
a[1]和a[2]差值为9-7=2,2*0.25=0.5
最终结果a[1]+0.5=7+0.5=7.5
import numpy as np
a=np.array([[1,7,9],[23,54,12]])
print(a)
"""
[[ 1 7 9]
[23 54 12]]
"""
print(np.percentile(a,50))
print(np.percentile(a,25))
print(np.percentile(a,77)) # 12+0.85*11
"""输出
10.5
7.5
21.35
"""
(1)axis=0
沿0轴方向(以列为单位算)
import numpy as np
a=np.array([[1,7,9],[23,54,12]])
print(a)
"""
[[ 1 7 9]
[23 54 12]]
"""
print(np.percentile(a,50,axis=0)) # 每列算平均 如(1+23)/2=12
print(np.percentile(a,25,axis=0)) # 按列算 如1和23: 1+0.25*22=6.5
print(np.percentile(a,77,axis=0)) # 如1和23: 1+0.77*22=17.94
"""
[12. 30.5 10.5]
[ 6.5 18.75 9.75]
[17.94 43.19 11.31]
"""
(2)axis=1
沿1轴方向(以行为单位算)
import numpy as np
a=np.array([[1,7,9],[23,54,12]])
print(a)
"""
[[ 1 7 9]
[23 54 12]]
"""
print(np.percentile(a,50,axis=1))
print(np.percentile(a,25,axis=1))
print(np.percentile(a,77,axis=1))
"""
[ 7. 23.]
[ 4. 17.5]
[ 8.08 39.74]
"""
4.median
计算排序后的中位数
import numpy as np
a=np.array([[1,7,9],[23,54,12]])
print(a)
"""
[[ 1 7 9]
[23 54 12]]
"""
print(np.median(a)) # 10.5
print(np.median(a,axis=0)) # [12. 30.5 10.5]
print(np.median(a,axis=1)) # [ 7. 23.]
5.mean
算术平均值
import numpy as np
a=np.array([[1,2,3],[4,5,6]])
print(a)
"""
[[1 2 3]
[4 5 6]]
"""
print(np.mean(a)) # (1+2+3+4+5+6)/6=3.5
print(np.mean(a,axis=0)) # 1和4: (1+4)/2=2.5
print(np.mean(a,axis=1)) # 1和2和3: (1+2+3)/3=2
"""
3.5
[2.5 3.5 4.5]
[2. 5.]
"""
6.average
加权平均值
各元素分别乘对应权重再求和,结果除以权重之和
import numpy as np
a=np.array([[1,2,3],[4,5,6]])
print(a)
"""
[[1 2 3]
[4 5 6]]
"""
print(np.average(a)) # 默认权重,与算术平均值相同
w=np.array([[2,4,2],[2,8,2]])
print(np.average(a,weights=w)) # (1*2+2*4+3*2+4*2+5*8+6*2)/(2+4+2+2+8+2)=3.8
wx=np.array([1,2])
print(np.average(a,axis=0,weights=wx)) # 如第一个数(1*1+4*2)/(1+2)=3
wy=np.array([1,2,3])
print(np.average(a,axis=1,weights=wy))
"""
3.5
3.8
[3. 4. 5.]
[2.33333333 5.33333333]
"""
7.方差var与标准差std
如
1 2 3 4
均值:2.5
方差:1.25
标准差:根号1.25
import numpy as np
a=np.array([1,2,3,4])
print(np.var(a)) # 1.25
print(np.std(a)) # 1.118033988749895
(五)排序、条件筛选函数
1.sort
sort(arr,axis,kind,order)
kind:排序方式(默认快排)
order:指定排序对象
import numpy as np
a=np.array([[7,2],[1,6]])
print(a)
"""
[[7 2]
[1 6]]
"""
print(np.sort(a)) # 等同于axis=1
print(np.sort(a,axis=1))
"""轴1排序(默认)
[[2 7]
[1 6]]
"""
print(np.sort(a,axis=0))
"""轴0排序
[[1 2]
[7 6]]
"""
# 注:np.msort is deprecated, use np.sort(a, axis=0) instead
指定排序对象
d=np.dtype([("name","S10"),("age",int)])
b=np.array([("peter",18),("jack",20)],dtype=d)
print(b) # [(b'peter', 18) (b'jack', 20)]
print(np.sort(b,order="name")) # [(b'jack', 20) (b'peter', 18)]
2.argsort
返回从小到大的索引值
import numpy as np
a=np.array([[2,7],[1,6]])
print(a)
"""
[[2 7]
[1 6]]
"""
print(np.argsort(a,axis=0))
"""
[[1 1]
[0 0]]
"""
print(np.argsort(a)) # axis=1
"""
[[0 1]
[0 1]]
"""
重构数组
import numpy as np
a=np.array([[2,7,4],[1,5,8],[9,4,1]])
print(a)
"""
[[2 7 4]
[1 5 8]
[9 4 1]]
"""
b=np.argsort(a)
print(b) # axis=1
"""
[[0 2 1]
[0 1 2]
[2 1 0]]
"""
print(a[b])
# b[0]是[0 2 1] 对应a[0]=[2 7 4],a[2]=[9 4 1]],a[1]=[1 5 8] 为输出第一块,后面以此类推
"""
[[[2 7 4]
[9 4 1]
[1 5 8]]
[[2 7 4]
[1 5 8]
[9 4 1]]
[[9 4 1]
[1 5 8]
[2 7 4]]]
"""
# 但似乎没有多大意义,对于一维,可以实现按序输出
c=np.array([5,4,2,1,6,3])
print(np.argsort(c)) # [3 2 5 1 0 4]
print(c[np.argsort(c)]) # [1 2 3 4 5 6]
3.lexsort
np.lexsort((third,second,first)) 参数优先级递减,即:先根据最后一个排,相等的话再根据倒数第二个排…
返回结果是索引下标
import numpy as np
a=(32,43,12,43,54)
b=(23,12,39,54,12)
c=(100,99,100,70,99)
k=np.lexsort((a,b,c))
print(k) # [3 1 4 0 2]
4.sort_complex
对于复数,先按照实部排序,若相同,再按照虚部排序
import numpy as np
a=np.array([9+3j,4+5j,4+7j,2+3j])
print(np.sort_complex(a))
# [2.+3.j 4.+5.j 4.+7.j 9.+3.j]
5.partition
分区排序
partition(arr,kth,axis,kind,order)
该函数会找到第kth小的数(从0起)[在手动计算时可以先从小到大排序,再以下标索引为kth]的数作为分界],保证该数左边都比他小,右边都比他大。左右两侧可以无序,具体的排列方式无法得知(据说是堆排和快排相结合的方式),但可以通过kind指定排序方式确定排列顺序
下面以先排序再索引角度说明
import numpy as np
a=np.array([8,4,2,1,7,5,9,2,4,6])
print(np.sort(a)) # [1 2 2 4 4 5 6 7 8 9] 下标索引5的数是5
print(np.partition(a,5)) # 5左边都比5小,右边都比5大
# [1 2 2 4 4 5 6 7 9 8]
a=np.array([[1,2,3],[4,5,6],[3,4,2]])
print(a)
"""
[[1 2 3]
[4 5 6]
[3 4 2]]
"""
print(np.partition(a,1,axis=0)) # 每列按1号元素[4 5 6]做分界
"""
[[1 2 2]
[3 4 3]
[4 5 6]]
"""
a=np.array([3,4,2,1,6,5,2,3,45,7,4,2])
print(np.sort(a)) # [ 1 2 2 2 3 3 4 4 5 6 7 45]
print(np.partition(a,(3,7))) # [ 1 2 2 2 3 3 4 4 45 7 6 5]
# 排序后下标索引为3的数是2,下标索引为7的数是4,2左边都比2小,4右边都比4大,在2和4之间的数在它们中间
6.argpartition
argpartition(a,kth,axis,kind,order)
与partition不同的是,argpartition的返回结果是索引值
如下例,排序后的2号索引元素是10,其左边都比10小,右边都比10大。例如10左边是0和1,对应原数组下标为6和4;而10对应的下标是5号,输出5;10右侧同理
同样,在10左右两侧的元素可能是乱序的,可以通过kind指明排序方式
import numpy as np
a=np.array([46,57,23,39,1,10,0,120])
print(np.sort(a)) # [ 0 1 10 23 39 46 57 120]
print(np.partition(a,2)) # [ 0 1 10 39 57 23 46 120]
print(np.argpartition(a,2)) # [6 4 5 3 1 2 0 7]
可以看出,虽然kth左右的元素是乱序的,但kth是在排序后的正确位置上,通过同样的索引我们可以输出该数组中第kth大/小的元素
如b[2]指明了从小到大的第2个元素(从0起)10在原数组的5号位置(从0起)
import numpy as np
a=np.array([46,57,23,39,1,10,0,120])
print(np.sort(a)) # [ 0 1 10 23 39 46 57 120]
print(np.partition(a,2)) # [ 0 1 10 39 57 23 46 120]
b=np.argpartition(a,2)
print(b[2]) # 5
我们也可以反过来找第2大(从1起)的元素下标
import numpy as np
a=np.array([46,57,23,39,1,10,0,120])
print(np.sort(a)) # [ 0 1 10 23 39 46 57 120]
print(np.partition(a,-2)) # 以57为分界,左边都比它小,右边都比它大
# [ 10 39 23 0 1 46 57 120]
b=np.argpartition(a,-2)
print(b[-2]) # 1
上文提到,我们可以同时指定多个元素的位置,并通过相同索引输出
import numpy as np
a=np.array([46,57,23,39,1,10,0,120])
print(np.sort(a)) # [ 0 1 10 23 39 46 57 120]
b=np.partition(a,(1,2)) # 确定1号和2号位置
print(b) # [ 0 1 10 39 57 23 46 120]
print(b[1]) # 1
print(b[2]) # 10
7.argmax和argmin
沿axis返回最大和最小元素
import numpy as np
a=np.arange(12).reshape(3,4)
print(a)
"""
[[ 0 1 2 3]
[ 4 5 6 7]
[ 8 9 10 11]]
"""
print(np.argmax(a)) # 整个数组的最大值11
print(np.argmax(a,axis=0)) # 按列输出最大值的索引:[2 2 2 2]
print(np.argmax(a,axis=1)) # 按行输出最大值的索引:[3 3 3]
print(np.argmin(a,axis=0)) # 按列输出最小值的索引:[0 0 0 0]
8.nonzero
返回非零元素的索引
import numpy as np
a=np.arange(12).reshape(3,4)
print(a)
"""
[[ 0 1 2 3]
[ 4 5 6 7]
[ 8 9 10 11]]
"""
print(np.nonzero(a)) # 输出坐标(array([x1,x2,x3,...]),array([y1,y2,y3,...]))
# (array([0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2], dtype=int64), array([1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3], dtype=int64))
9.where
返回满足给定条件的索引
import numpy as np
a=np.arange(12).reshape(3,4)
print(a)
"""
[[ 0 1 2 3]
[ 4 5 6 7]
[ 8 9 10 11]]
"""
print(np.where(a>9)) # 输出坐标(array([x1,x2,x3,...]),array([y1,y2,y3,...]))
# (array([2, 2], dtype=int64), array([2, 3], dtype=int64))
10.extract
根据指定条件输出对应元素
import numpy as np
a=np.arange(12).reshape(3,4)
print(a)
"""
[[ 0 1 2 3]
[ 4 5 6 7]
[ 8 9 10 11]]
"""
tiaojian=a>9 # 判断条件为a>2
print(tiaojian)
"""
[[False False False False]
[False False False False]
[False False True True]]
"""
print(np.extract(tiaojian,a)) # [10 11]
九.字节交换
大端模式:数据的高字节保存在内存的低地址中,即先存高字节
小端模式:数据的低字节保存在内存的低地址中,即先存低字节
1.map与hex
map() 用来处理每个元素,可以通过列表的形式输出
hex表示16进制输出
import numpy as np
a=np.array([1,128,256],dtype="i2")
b=map(hex,a)
print(b) # <map object at 0x000001467793F220>
print(list(b)) # ['0x1', '0x80', '0x100']
2.字节交换
byteswap() 方法通过交换数组中每个元素的字节来更改数组的字节顺序。默认情况下,它会创建一个新的数组,并交换其字节顺序。但是,如果将 inplace 参数设置为 True,则会在原始数组本身中交换字节顺序。
例如,对于一个16位整数值 0x1234,在大端序中,它的字节顺序是 0x12 0x34,而在小端序中,它的字节顺序是 0x34 0x12。因此,调用 byteswap() 方法后,它的字节顺序会被交换成 0x34 0x12。
①-5的交换
-5的十六进制是 -0x5
其有符号整数的二进制原码:1000 0000 0000 0101
补码:1111 1111 1111 1011
互换后的补码:1111 1011 1111 1111
这是一个负数,原码:1000 0100 0000 0001
输出 -0x401
②128的交换
128的十六进制是0x80
其有符号整数的二进制原码:0000 0000 1000 0000
交换:1000 0000 0000 0000
这是一个负数,负数在计算机中是以补码存储的
对应原码:1000 0000 0000 0000
输出 -0x8000
③256的交换
256的十六进制是0x100
交换后是0x0001
输出0x1
import numpy as np
a=np.array([-5,128,256],dtype=np.int16)
print(list(map(hex,a))) # ['-0x5', '0x80', '0x100']
a.byteswap(inplace=True) # 字节交换
print(list(map(hex,a)))
"""
['-0x401', '-0x8000', '0x1']
"""
[练习] 0x87 → -0x7900
以上在交换的过程中出现了正负的转换,若不希望转换,可以使用uint将它们强制转换为无符号整数类型
import numpy as np
a=np.array([5,135,256],dtype=np.uint16)
print(list(map(hex,a))) # ['0x5', '0x87', '0x100']
a.byteswap(inplace=True)
print(list(map(hex,a)))
"""0005→0500 0087→8700 0100→0001
['0x500', '0x8700', '0x1']
"""
十.副本和视图
1.视图
普通视图对象的修改不会影响原数组
import numpy as np
a=np.array([[1,2,3],[4,5,6],[7,8,9],[10,11,12]])
print(a)
"""
[[ 1 2 3]
[ 4 5 6]
[ 7 8 9]
[10 11 12]]
"""
b=a.view() # 创建视图
b.shape=(3,4) # 修改b
print(a) # a不受影响
"""
[[ 1 2 3]
[ 4 5 6]
[ 7 8 9]
[10 11 12]]
"""
对切片的修改会影响原数组
import numpy as np
a=np.array([[1,2,3],[4,5,6],[7,8,9],[10,11,12]])
print(a)
"""
[[ 1 2 3]
[ 4 5 6]
[ 7 8 9]
[10 11 12]]
"""
b=a[2:] # 切片
print(b)
"""
[[ 7 8 9]
[10 11 12]]
"""
b[0]=[1,2,3]
print(a) # a受到影响
"""
[[ 1 2 3]
[ 4 5 6]
[ 1 2 3]
[10 11 12]]
"""
2.副本
对副本的修改不会影响原数组
import numpy as np
a=np.array([[1,2,3],[4,5,6],[7,8,9],[10,11,12]])
print(a)
"""
[[ 1 2 3]
[ 4 5 6]
[ 7 8 9]
[10 11 12]]
"""
b=a.copy() # 创建副本
b.shape=(3,4) # 修改b
print(a) # a不受影响
"""
[[ 1 2 3]
[ 4 5 6]
[ 7 8 9]
[10 11 12]]
"""
关于拷贝和内存地址的更多内容见
十一.线性代数
1.dot
数组点积:将数组视为矩阵,按矩阵乘法计算
import numpy as np
a=np.array([[1,2],[3,4]])
print(a)
"""
[[1 2]
[3 4]]
"""
b=np.array([[5,6],[7,8]])
print(b)
"""
[[5 6]
[7 8]]
"""
print(np.dot(a,b))
"""
[[19 22]
[43 50]]
"""
2.vdot
向量点积:对应位置的元素相乘再求和
import numpy as np
a=np.array([[1,2],[3,4]])
print(a)
"""
[[1 2]
[3 4]]
"""
b=np.array([[5,6],[7,8]])
print(b)
"""
[[5 6]
[7 8]]
"""
print(np.vdot(a,b)) # 1*5+2*6+3*7+4*8=70
如果参数是多维数组,会展开再计算
如果参数是复数,那么它的共轭复数会参与运算
先来认识一下conj函数(用于计算一个复数的共轭 a+bj→a-bj)
import numpy as np
a = np.array([1+2j, 3-4j])
b = np.conj(a)
print(a) # [1.+2.j 3.-4.j]
print(b) # [1.-2.j 3.+4.j]
而np.vdot作用是
np.vdot(a, b) = np.conj(a[0])*b[0] + np.conj(a[1])*b[1]+...
其中a[0]表示数组a的第一个元素,a[1]表示数组a的第二个元素…
来看下面的例子
import numpy as np
a=np.array([1+2j,3+4j])
print(a) # [1.+2.j 3.+4.j]
b=np.array([5+6j,7+8j])
print(b) # [5.+6.j 7.+8.j]
print(np.vdot(a,b)) # (70-8j)
其中np.vdot(a, b) = (1+2j)*np.conj(5+6j) + (3+4j)*np.conj(7+8j)
= (1-2j)*(5+6j) + (3-4j)*(7+8j) (按乘法分配律,且 j²=-1)
= 5+6j-10j-12j² + 21+24j-28j-32j²
= 5+6j-10j+12 + 21+24j-28j+32
= 70-8j
3.inner
数组内积
(1)一维数组的内积等于向量点积
import numpy as np
a = np.array([1, 2, 3])
b = np.array([4, 5, 6])
inner_product = np.inner(a, b) # 1*4+2*5+3*6
vdot_product = np.vdot(a, b)
print(inner_product) # 32
print(vdot_product) # 32
(2)二维数组的内积
c数组的计算方式为:
1*5+2*6, 1*7+2*8
3*5+4*6, 3*7+4*8
import numpy as np
a = np.array([[1, 2], [3, 4]])
b = np.array([[5, 6], [7, 8]])
c = np.inner(a, b)
print(c)
"""
[[17 23]
[39 53]]
"""
4.matmul
矩阵乘积:计算的是矩阵乘法
import numpy as np
a=[[1,2],[3,4]]
b=[[5,6],[7,8]]
print(np.matmul(a,b))
"""
[[19 22]
[43 50]]
"""
(1)一维乘二维
①符合规则
import numpy as np
a=[[1,2],[3,4]]
b=[1,2]
print(np.matmul(b,a)) # [ 7 10]
②不符合规则
将b转置进行运算,将得到的结果进行转置再输出
import numpy as np
a=[[1,2],[3,4]]
b=[1,2] # 行向量
print(np.matmul(a,b)) # [ 5 11]
注:对于一维列向量不能自动转置
import numpy as np
a = [[1, 2], [3, 4]]
b = [[1],[2]] # 列向量
print(np.matmul(b, a)) # ValueError
(2)维度大于2
分别计算(小的广播)
import numpy as np
a = [[[1, 2], [3, 4]],[[5,6],[7,8]]]
b = [[1,2],[3,4]]
print(np.matmul(a, b))
"""
[[[ 7 10]
[15 22]]
[[23 34]
[31 46]]]
"""
(3)matmul与dot的区别
①二者对于两个二维数组的相乘计算结果是一样的
import numpy as np
a=[[1,2],[3,4]]
b=[[5,6],[7,8]]
print(np.matmul(a,b))
print(np.dot(a,b))
"""输出均为
[[19 22]
[43 50]]
"""
②matmul不能计算标量相乘
import numpy as np
a=[[1,2],[3,4]]
print(np.dot(a,2)) # 数组元素×2
"""
[[2 4]
[6 8]]
"""
print(np.matmul(a,2)) # ValueError
③多维数组
import numpy as np
a=np.arange(12).reshape(2,3,2)
b=np.arange(16).reshape(2,2,4)
print(np.matmul(a,b)) # 各块分别相乘
"""
[[[ 4 5 6 7]
[ 12 17 22 27]
[ 20 29 38 47]]
[[132 145 158 171]
[172 189 206 223]
[212 233 254 275]]]
"""
print(np.dot(a,b))
"""
[[[[ 4 5 6 7]
[ 12 13 14 15]]
[[ 12 17 22 27]
[ 52 57 62 67]]
[[ 20 29 38 47]
[ 92 101 110 119]]]
[[[ 28 41 54 67]
[132 145 158 171]]
[[ 36 53 70 87]
[172 189 206 223]]
[[ 44 65 86 107]
[212 233 254 275]]]]
"""
print(np.dot(a,b).shape) # (2, 3, 2, 4)
从dot的输出结果来看,一共有2个三维数组,每个三维数组包括3个二维数组,每个二维数组包括2个一维数组,每个一维数组包括4个元素,所以shape为(2, 3, 2, 4)
dot的计算方式如下
a数组共有2块(由2个二维数组组成),因此输出结果有2个三维数组。我们用a的第1块的每行(第一个二维数组的第一个一维数组)分别乘b的每块(每个二维数组)即可得到输出结果的第一个三维数组的第一个二维数组
简单说
输出第一行=a的第一行(0和1)与b的第一块(0~7)相乘,得到结果(4 5 6 7)
输出第二行=a的第一行(0和1)与b的第二块(8~15)相乘,得到结果(12 13 14 15)
输出第三行=a的第二行(2和3)与b的第一块(0~7)相乘,得到结果(12 17 22 27)
输出第四行=a的第二行(4和5)与b的第二块(8~15)相乘,得到结果(52 57 62 67)
5.linalg.det
计算行列式
import numpy as np
a=np.array([[1,2],[3,4]])
print(np.linalg.det(a)) # -2.0000000000000004
6.linalg.slove
解线性方程组
如
x+2y=4
2x+y=5
系数矩阵做a,等号右边做b
可解得x=2,y=1
import numpy as np
a=np.array([[1,2],[2,1]])
b=np.array([[4],[5]])
print(np.linalg.solve(a,b))
"""
[[2.]
[1.]]
"""
7.linalg.inv
求逆矩阵
import numpy as np
a=np.array([[1,2],[3,4]])
print(np.linalg.inv(a))
"""
[[-2. 1. ]
[ 1.5 -0.5]]
"""
对于以上方程组,也可以通过逆矩阵求解(a可逆)(k为x和y的解)
ak=b
k=a-1b
import numpy as np
a=np.array([[1,2],[2,1]])
b=np.array([[4],[5]])
print(np.dot(np.linalg.inv(a),b))
"""
[[2.]
[1.]]
"""
十二.I/O
1.save/load
save:存储数组到指定位置的指定文件(若没有该文件会自动创建),后缀名默认.npy,可省略
load:从指定位置的指定文件中读取数组,必须加上后缀.npy
import numpy as np
a=np.array([1,2,3])
np.save("D:\wenjianming",a) # 存储数组
b=np.load("D:\wenjianming.npy") # 读取数组
print(b) # [1 2 3]
2.savez/load
savez:保存多个数组的数据
.files: 查看各数组的名称
非关键字参数会自动起名arr_0、arr_1、arr_2…
import numpy as np
a=np.array([1,2,3])
b=np.array([[1,2,3],[4,5,6]])
np.savez("D:\wenjianming2",a,b)
c=np.load("D:\wenjianming2.npz")
print(c.files) # 查看各数组的名称:['arr_0', 'arr_1']
print(c["arr_0"]) # 输出a数组:[1 2 3]
print(c["arr_1"])
"""输出b数组
[[1 2 3]
[4 5 6]]
"""
我们也可以指定关键字名称
import numpy as np
a=np.array([1,2,3])
b=np.array([[1,2,3],[4,5,6]])
np.savez("D:\wenjianming3",a,bdekeyname=b) # 给数组b指定关键字名称bdekeyname,关键字参数必须放在最后
c=np.load("D:\wenjianming3.npz")
print(c["bdekeyname"])
"""输出b数组
[[1 2 3]
[4 5 6]]
"""
3.savetxt/loadtxt
import numpy as np
a=np.array([1,2,3])
np.savetxt("D:\wenjianming.txt",a) # 必须指明txt后缀
b=np.loadtxt("D:\wenjianming.txt")
print(b) # [1. 2. 3.]
import numpy as np
a=np.array([1,2,3])
np.savetxt("D:\wenjianming2.txt",a,fmt="%d") # fmt="%d"存储为整数
十三.Matplotlib
cmd安装
pip3 install matplotlib -i https://pypi.tuna.tsinghua.edu.cn/simple
使用 python -m pip list 验证安装是否成功
1.plot/show
import matplotlib.pyplot as plt
import numpy as np
x=np.arange(1,11) # 左闭右开
y=2*x+5
plt.title("标题")
plt.xlabel("x轴")
plt.ylabel("y轴")
plt.plot(x,y) # 绘图
plt.show() # 展示
可以看到,中文的显示出了一些问题
下载SourceHanSansSC-Bold.otf
链接:https://pan.baidu.com/s/1BG0ii5GRkO0-VyDkhJg6WA?pwd=cgzg
提取码:cgzg
import matplotlib
import matplotlib.pyplot as plt
import numpy as np
ziti=matplotlib.font_manager.FontProperties(fname="D:/py字体/SourceHanSansSC-Bold.otf")
x=np.arange(1,11) # (start,stop(不含),step)
y=2*x+5
plt.title("标题",fontproperties=ziti)
plt.xlabel("x轴",fontproperties=ziti)
plt.ylabel("y轴",fontproperties=ziti)
plt.plot(x,y) # 绘图
plt.show() # 展示
2.格式化字符
其他的格式化见下图
颜色
3.绘制正弦波
import matplotlib
import matplotlib.pyplot as plt
import numpy as np
ziti=matplotlib.font_manager.FontProperties(fname="D:/py字体/SourceHanSansSC-Bold.otf")
x=np.arange(0,2*np.pi,0.1)
y=np.sin(x)
plt.title("标题",fontproperties=ziti)
plt.xlabel("x轴",fontproperties=ziti)
plt.ylabel("y轴",fontproperties=ziti)
plt.plot(x,y,"m") # 绘图
plt.show() # 展示
4.subpolt
在同一图像中绘制多个函数
subpolt(行,列,序号(从1起))
import matplotlib.pyplot as plt
import numpy as np
x=np.arange(0,2*np.pi,0.1)
a=np.sin(x)
b=np.cos(x)
plt.subplot(2,1,1) # 2行1列,序号1
plt.title("sin x")
plt.plot(x,a) # x轴为x,y轴为a
plt.subplot(2,1,2) # 2行1列,序号2
plt.title("cos x")
plt.plot(x,b) # x轴为x,y轴为b
plt.show() # 展示
更多的图
import matplotlib.pyplot as plt
import numpy as np
x=np.arange(0,2*np.pi,0.1)
a=np.sin(x)
b=np.cos(x)
c=np.tan(x)
d=np.arcsin(x)
plt.subplot(2,2,1) # 2行2列,序号1
plt.title("sin x")
plt.plot(x,a)
plt.subplot(2,2,2) # 序号2,第一行右侧图
plt.title("cos x")
plt.plot(x,b)
plt.subplot(2,2,3) # 序号3,第二行左边图
plt.title("tan x")
plt.plot(x,c)
plt.subplot(2,2,4) # 序号4,第二行右边图
plt.title("arcsin x")
plt.plot(x,d)
plt.show() # 展示
5.bar
条形图
import matplotlib.pyplot as plt
x1=[1,3,5]
y1=[11,12,13]
x2=[2,4,6]
y2=[9,14,12]
plt.bar(x1,y1,align="center")
plt.bar(x2,y2,color="g",align="center")
plt.title("title")
plt.show()
6.histogram
指定区间数据的个数
histogram(a,bins=10,range=None,weights=None,density=False)
a:待处理数组
bins:一个整数或标量数组
weights:为数组的每个元素指定的权值
density:默认为False,输出各区间的元素个数。为True时输出每个区间的概率密度
(1)当bins为标量数组时
如下例,bins=[0, 20, 40, 60, 80, 100] ,输出的hist表示数组中在各个区间 [0,20)、[20,40)、[40,60)、[60,80)、[80,100)的元素个数,bins输出为各间隔的边界
import numpy as np
a = np.array([22, 87, 5, 43, 56, 73, 55, 54, 11, 20, 51, 5, 79, 31, 27])
print(np.sort(a)) # [ 5 5 11 | 20 22 27 31 | 43 51 54 55 56 | 73 79 | 87]
hist,bins=np.histogram(a,bins=[0, 20, 40, 60, 80, 100])
print(hist) # [3 4 5 2 1]
print(bins) # [ 0 20 40 60 80 100]
(2)当bins为整数时
一般配合range使用,指定所选范围
我们可以将上例改为
指定的整数bins表示划分间隔(=hist的数量=输出bins的数量-1)
这里输出的bins是指定的整数bins和range结合的结果
import numpy as np
a = np.array([22, 87, 5, 43, 56, 73, 55, 54, 11, 20, 51, 5, 79, 31, 27])
print(np.sort(a)) # [ 5 5 11 | 20 22 27 31 | 43 51 54 55 56 | 73 79 | 87]
hist,bins=np.histogram(a,bins=5,range=(0,100))
print(hist) # [3 4 5 2 1]
print(bins) # [ 0. 20. 40. 60. 80. 100.]
7.plt
绘图
横轴为各区间
纵轴为各区间元素个数
from matplotlib import pyplot as plt
import numpy as np
a = np.array([22, 87, 5, 43, 56, 73, 55, 54, 11, 20, 51, 5, 79, 31, 27])
print(np.sort(a)) # [ 5 5 11 | 20 22 27 31 | 43 51 54 55 56 | 73 79 | 87]
plt.hist(a, bins=[0, 20, 40, 60, 80, 100])
plt.show()