NumPy库的应用

NumPy为什么如此高效

  • NumPy是由C语言编写,C语言执行时,对代码整体编译,速度更快
  • NumPy数组内的数据类型必须是统一的,在遍历过程中不用再判断类型
  • NumPy数组内的数据连续存储在内存中,而Python列表的数据分散存储在内存中
  • Python执行时有线程锁,无法做到真正的多线程并行,而C语言可以

Numpy数组的创建

从列表开始创建

import numpy as np
x=np.array([1,2,3,4,5])
print(x)
print(type(x))
print(x.shape)
  • 设置数组的数据类型
x=np.array([1,2,3,4,5],dtype="float32")
print(x)
print(type(x[0]))
[1. 2. 3. 4. 5.]
<class 'numpy.float32'>
  • 二维数组
x=np.array([[1,2,3],
          [4,5,6],
          [7,8,9]])
print(x)
print(x.shape)
[[1 2 3]
 [4 5 6]
 [7 8 9]]
(3, 3)

从头创建数组

(1)创建 长度为5的数组,值都为0

np.zeros(5,dtype=int)
array([0, 0, 0, 0, 0])

(2)创建一个2*4的浮点型数组,值都为1

np.ones((2,4),dtype=float)
array([[1., 1., 1., 1.],
       [1., 1., 1., 1.]])

(3)创建一个3*5的数组,值都为8.8

np.full((3,5),8.8)
array([[8.8, 8.8, 8.8, 8.8, 8.8],
       [8.8, 8.8, 8.8, 8.8, 8.8],
       [8.8, 8.8, 8.8, 8.8, 8.8]])

(4)创建一个3*3的单位矩阵

np.eye(3)
array([[1., 0., 0.],
       [0., 1., 0.],
       [0., 0., 1.]])

(5) 创建一个线性序列数组,从1开始,到15结束,步长为2

np.arange(1,15,2)
array([ 1,  3,  5,  7,  9, 11, 13])

(6)创建一个4个元素的数组,这四个数均匀的分配到0~1

np.linspace(0,1,4)
array([0.        , 0.33333333, 0.66666667, 1.        ])

(7)创建一个10个元素的数组,形成1~10^9的等比数列

np.logspace(0,9,10)
array([1.e+00, 1.e+01, 1.e+02, 1.e+03, 1.e+04, 1.e+05, 1.e+06, 1.e+07,
       1.e+08, 1.e+09])

(8)创建一个3*3的,在0~1之间均匀分布的随机数构成的数组

np.random.random((3,3))
array([[0.49982012, 0.67828982, 0.73930433],
       [0.43127096, 0.79784298, 0.8559498 ],
       [0.50034775, 0.72711364, 0.35867165]])

(9)创建一个3*3的,均值为0,标准差为1的正态分布随机数构成的数组

np.random.normal(0,1,(3,3))
array([[-0.88215024, -0.63194594, -0.84818543],
       [-0.40218622,  0.28294795,  2.95492175],
       [ 0.03232202, -0.30333955,  0.20539643]])

(10)创建一个3*3的,在(0,10)之间随机整数构成的数组

np.random.randint(0,10,(3*3))
array([5, 2, 5, 4, 8, 4, 0, 0, 6])

(11)随机重排列

x=np.array([10,20,30,40])
np.random.permutation(x) #生产新列表
array([40, 10, 30, 20])
print(x)
np.random.shuffle(x) #修改原列表
print(x)
[10 20 30 40]
[20 30 40 10]

(12)随机采样

  • 按指定形状采样
x=np.arange(10,25,dtype=float)
np.random.choice(x,size=(4,3))
array([[12., 23., 22.],
       [21., 11., 17.],
       [16., 11., 15.],
       [10., 20., 14.]])
  • 按概率采样
np.random.choice(x,size=(4,3),p=x/np.sum(x))
array([[22., 16., 22.],
       [12., 23., 21.],
       [17., 21., 13.],
       [14., 20., 19.]])

NumPy数组的性质

数组的属性

x=np.random.randint(10,size=(3,4))
x
array([[8, 9, 3, 1],
       [4, 5, 1, 5],
       [7, 1, 3, 3]])

1.数组的形状shape

x.shape
(3, 4)

2.数组的维度ndim

x.ndim
2

3.数组的大小size

x.size
12

4.数组的数据类型dtype

x.dtype
dtype('int32')

数组索引

1.一维数组的索引

x1=np.arange(10)
x1[0]
x1[1]
x1[-1]
9

2.多维数组的索引——以二维为例

x2=np.random.randint(0,20,(2,3))
x2
array([[13, 15, 16],
       [15, 18,  4]])
x2[0,0]
13
x2[0][0]
13

数组的切片

1.一维数组——和列表一样

2.多维数组——以二维为例

x2=np.random.randint(20,size=(3,4))
x2
array([[11, 16,  0,  3],
       [ 5,  7, 10,  8],
       [15,  4,  4, 13]])
x2[:2,:3] # 前两行 前三列
array([[11, 16,  0],
       [ 5,  7, 10]])
x2[:2,0:3:2] # 前两行 前三列(每隔一列)
array([[11,  0],
       [ 5, 10]])
x2[::-1,::-1]
array([[13,  4,  4, 15],
       [ 8, 10,  7,  5],
       [ 3,  0, 16, 11]])

3.获取数组的行和列

x3=np.random.randint(20,size=(3,4))
x3
array([[ 7, 17, 17, 13],
       [ 4, 13,  7, 10],
       [19, 18,  1,  6]])
x3[1,:]
array([ 4, 13,  7, 10])
x3[1] # 第一行简写
array([ 4, 13,  7, 10])
x3[:,1]
array([17, 13, 18])

4.切片获取是时视图,而非副本

x4=np.random.randint(20,size=(3,4))
x4
array([[12,  5, 16, 12],
       [ 5,  4, 16,  4],
       [ 7,  6, 11,  4]])
x5=x4[:2,:2]
x5
array([[12,  5],
       [ 5,  4]])

注意:视图元素发生修改,则原数组也发生修改

x5[0][0]=0
x5
array([[0, 5],
       [5, 4]])
x4
array([[ 0,  5, 16, 12],
       [ 5,  4, 16,  4],
       [ 7,  6, 11,  4]])

修改切片的安全方式:copy

x4=np.random.randint(20,size=(3,4))
x4
array([[ 1, 16,  9, 16],
       [18, 14, 10, 17],
       [17,  3,  6, 11]])
x6=x4[:2,:2].copy()
x6
array([[ 1, 16],
       [18, 14]])
x6[0][0]=0
x6
array([[ 0, 16],
       [18, 14]])
x4
array([[ 1, 16,  9, 16],
       [18, 14, 10, 17],
       [17,  3,  6, 11]])

数组的变形

x5=np.random.randint(0,10,(12,))
x5
array([3, 0, 6, 6, 7, 0, 4, 3, 6, 3, 2, 6])
x5.shape
(12,)
x6=x5.reshape(3,4)
x6
array([[3, 0, 6, 6],
       [7, 0, 4, 3],
       [6, 3, 2, 6]])

注意:reshape返回的是视图,而非副本

x6[0][0]=0
x5
array([0, 0, 6, 6, 7, 0, 4, 3, 6, 3, 2, 6])

一维向量转行向量

x7=x5.reshape(1,x5.shape[0])
x7
array([[0, 0, 6, 6, 7, 0, 4, 3, 6, 3, 2, 6]])
x8=x5[np.newaxis,:]
x8
array([[0, 0, 6, 6, 7, 0, 4, 3, 6, 3, 2, 6]])

一维向量转列向量

x7=x5.reshape(x5.shape[0],1)
x7
array([[0],
       [0],
       [6],
       [6],
       [7],
       [0],
       [4],
       [3],
       [6],
       [3],
       [2],
       [6]])
x8=x5[:,np.newaxis]
x8
array([[0],
       [0],
       [6],
       [6],
       [7],
       [0],
       [4],
       [3],
       [6],
       [3],
       [2],
       [6]])

多维向量转一维向量

x6=np.random.randint(0,10,(3,4))
x6
array([[5, 1, 2, 0],
       [7, 5, 6, 1],
       [3, 7, 6, 1]])

flatten返回的是副本

x9=x6.flatten()
x9
array([5, 1, 2, 0, 7, 5, 6, 1, 3, 7, 6, 1])

ravel返回的是视图

x10=x6.ravel()
x10
array([5, 1, 2, 0, 7, 5, 6, 1, 3, 7, 6, 1])
x10[0]=0
x6
array([[0, 1, 2, 0],
       [7, 5, 6, 1],
       [3, 7, 6, 1]])

reshape返回的是视图

x11=x6.reshape(-1)
x11
array([10,  1,  2,  0,  7,  5,  6,  1,  3,  7,  6,  1])
x11[0]=10
x6
array([[10,  1,  2,  0],
       [ 7,  5,  6,  1],
       [ 3,  7,  6,  1]])

数组的拼接

x1=np.array([[1,2,3],
            [4,5,6]])
x2=np.array([[7,8,9],
            [0,1,2]])

1.水平拼接——非视图

x3=np.hstack([x1,x2])
x3
array([[1, 2, 3, 7, 8, 9],
       [4, 5, 6, 0, 1, 2]])
x3[0][0]=0
x1
array([[1, 2, 3],
       [4, 5, 6]])
x4=np.c_[x1,x2]
x4
array([[1, 2, 3, 7, 8, 9],
       [4, 5, 6, 0, 1, 2]])
x4[0][0]=0
x1
array([[1, 2, 3],
       [4, 5, 6]])

2.垂直拼接——非视图

x1=np.array([[1,2,3],
            [4,5,6]])
x2=np.array([[7,8,9],
            [0,1,2]])
x5=np.vstack([x1,x2])
x5
array([[1, 2, 3],
       [4, 5, 6],
       [7, 8, 9],
       [0, 1, 2]])
x6=np.r_[x1,x2]
x6
array([[1, 2, 3],
       [4, 5, 6],
       [7, 8, 9],
       [0, 1, 2]])

数组的分裂

1.split的用法

x6=np.arange(10)
x6
array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
x1,x2,x3=np.split(x6,[2,7])
print(x1,x2,x3)
[0 1] [2 3 4 5 6] [7 8 9]

2.hsplit的用法

x7=np.arange(1,26).reshape(5,5)
x7
array([[ 1,  2,  3,  4,  5],
       [ 6,  7,  8,  9, 10],
       [11, 12, 13, 14, 15],
       [16, 17, 18, 19, 20],
       [21, 22, 23, 24, 25]])
right,middle,left=np.hsplit(x7,[2,4])
print("right:\n",right)     # 0~1列
print("middle:\n",middle)   # 2~3列
print("left:\n",left)       # 4列
right:
 [[ 1  2]
 [ 6  7]
 [11 12]
 [16 17]
 [21 22]]
middle:
 [[ 3  4]
 [ 8  9]
 [13 14]
 [18 19]
 [23 24]]
left:
 [[ 5]
 [10]
 [15]
 [20]
 [25]]

3.vsplit的用法

x7=np.arange(1,26).reshape(5,5)
x7
array([[ 1,  2,  3,  4,  5],
       [ 6,  7,  8,  9, 10],
       [11, 12, 13, 14, 15],
       [16, 17, 18, 19, 20],
       [21, 22, 23, 24, 25]])
upper,middle,lower=np.vsplit(x7,[2,4])
print("upper:\n",upper)
print("middle:\n",middle)
print("lower:\n",lower)
upper:
 [[ 1  2  3  4  5]
 [ 6  7  8  9 10]]
middle:
 [[11 12 13 14 15]
 [16 17 18 19 20]]
lower:
 [[21 22 23 24 25]]

NumPy四大运算

向量化运算

1.与数字的加减乘除等

x1=np.arange(1,6)
x1
array([1, 2, 3, 4, 5])
print("x1+5",x1+5)
print("x1-5",x1-5)
print("x1*5",x1*5)
print("x1/5",x1/5)
x1+5 [ 6  7  8  9 10]
x1-5 [-4 -3 -2 -1  0]
x1*5 [ 5 10 15 20 25]
x1/5 [0.2 0.4 0.6 0.8 1. ]
print("-x1",-x1)
print("x1**5",x1**5)
print("x1//5",x1//5)
print("x1%5",x1%5)
-x1 [-1 -2 -3 -4 -5]
x1**5 [   1   32  243 1024 3125]
x1//5 [0 0 0 0 1]
x1%5 [1 2 3 4 0]

2.绝对值、三角函数、指数、对数

(1)绝对值

x2=np.array([1,-1,2,-2,0])
x2
array([ 1, -1,  2, -2,  0])
abs(x2)
array([1, 1, 2, 2, 0])
np.abs(x2)
array([1, 1, 2, 2, 0])

(2)三角函数

theta=np.linspace(0,np.pi,3)
theta
array([0.        , 1.57079633, 3.14159265])
print("sin(theta)",np.sin(theta))
print("cos(thera)",np.cos(theta))
print("tan(thera)",np.tan(theta))
sin(theta) [0.0000000e+00 1.0000000e+00 1.2246468e-16]
cos(thera) [ 1.000000e+00  6.123234e-17 -1.000000e+00]
tan(thera) [ 0.00000000e+00  1.63312394e+16 -1.22464680e-16]
x=[1,0,-1]
print("arcsin(x)",np.arcsin(x))
print("arccos(x)",np.arccos(x))
print("arctan(x)",np.arctan(x))
arcsin(x) [ 1.57079633  0.         -1.57079633]
arccos(x) [0.         1.57079633 3.14159265]
arctan(x) [ 0.78539816  0.         -0.78539816]

(3)指数运算

x=np.arange(3)
x
array([0, 1, 2])
np.exp(x)
array([1.        , 2.71828183, 7.3890561 ])

(4)对数运算

x=np.array([1,2,4,8,10])
print("ln(x)",np.log(x))
print("log2(x)",np.log2(x))
print("log10(x)",np.log10(x))
ln(x) [0.         0.69314718 1.38629436 2.07944154 2.30258509]
log2(x) [0.         1.         2.         3.         3.32192809]
log10(x) [0.         0.30103    0.60205999 0.90308999 1.        ]

3.两个数组的运算

x1=np.arange(1,6)
x1
array([1, 2, 3, 4, 5])
x2=np.arange(6,11)
x2
array([ 6,  7,  8,  9, 10])
print("x1+x2",x1+x2)
print("x1-x2",x1-x2)
print("x1*x2",x1*x2)
print("x1/x2",x1/x2)
x1+x2 [ 7  9 11 13 15]
x1-x2 [-5 -5 -5 -5 -5]
x1*x2 [ 6 14 24 36 50]
x1/x2 [0.16666667 0.28571429 0.375      0.44444444 0.5       ]

矩阵运算

x=np.arange(9).reshape(3,3)
x
array([[0, 1, 2],
       [3, 4, 5],
       [6, 7, 8]])
  • 矩阵的转置
y=x.T
y
array([[0, 3, 6],
       [1, 4, 7],
       [2, 5, 8]])
  • 矩阵乘法
x=np.array([[1,0],
           [1,1]])
y=np.array([[0,1],
            [1,1]])
x.dot(y)
array([[0, 1],
       [1, 2]])
np.dot(x,y)
array([[0, 1],
       [1, 2]])
y.dot(x)
array([[1, 1],
       [2, 1]])
np.dot(y,x)
array([[1, 1],
       [2, 1]])

注意跟x*y的区别

x*y
array([[0, 0],
       [1, 1]])

广播运算

x=np.arange(3).reshape(1,3)
x
array([[0, 1, 2]])
x+5
array([[5, 6, 7]])

规则

如果两个数组的形状在维度上不匹配 那么数组的形式会沿着维度为1的维度进行扩展以匹配另一个数组的形状。
x1=np.ones((3,3))
x1
array([[1., 1., 1.],
       [1., 1., 1.],
       [1., 1., 1.]])
x2=np.arange(3).reshape(1,3)
x2
array([[0, 1, 2]])
x1+x2
array([[1., 2., 3.],
       [1., 2., 3.],
       [1., 2., 3.]])
x3=np.logspace(1,10,10,base=2).reshape(2,5)
x3
array([[   2.,    4.,    8.,   16.,   32.],
       [  64.,  128.,  256.,  512., 1024.]])
x4=np.array([[1,2,4,8,16]])
x4
array([[ 1,  2,  4,  8, 16]])
x3/x4
array([[ 2.,  2.,  2.,  2.,  2.],
       [64., 64., 64., 64., 64.]])
x5=np.arange(3).reshape(3,1)
x5
array([[0],
       [1],
       [2]])
x6=np.arange(3).reshape(1,3)
x6
array([[0, 1, 2]])
x5+x6
array([[0, 1, 2],
       [1, 2, 3],
       [2, 3, 4]])

比较运算和掩码

1.比较运算

x1=np.random.randint(100,size=(10,10))
x1
array([[36, 54, 38, 78, 27, 88, 70, 40, 61, 23],
       [24, 22, 28, 25,  8, 63, 36, 52, 92, 48],
       [ 0, 34, 79, 48, 36, 62, 31, 23, 70, 73],
       [ 9, 50, 51, 27, 49, 91, 74, 85, 52, 27],
       [10, 53,  4, 57, 68, 24, 96, 49, 52, 18],
       [59,  8, 87, 75, 34, 35, 94, 83, 69, 78],
       [28, 15, 73, 56, 26, 46, 46,  9, 82, 19],
       [ 7, 40, 80, 39, 90, 26, 67,  5, 43, 76],
       [72, 20, 52, 10, 23,  3, 86, 43, 51, 86],
       [ 1, 59, 56, 28, 86, 53, 50, 85, 75, 87]])
x1>50
array([[False,  True, False,  True, False,  True,  True, False,  True,
        False],
       [False, False, False, False, False,  True, False,  True,  True,
        False],
       [False, False,  True, False, False,  True, False, False,  True,
         True],
       [False, False,  True, False, False,  True,  True,  True,  True,
        False],
       [False,  True, False,  True,  True, False,  True, False,  True,
        False],
       [ True, False,  True,  True, False, False,  True,  True,  True,
         True],
       [False, False,  True,  True, False, False, False, False,  True,
        False],
       [False, False,  True, False,  True, False,  True, False, False,
         True],
       [ True, False,  True, False, False, False,  True, False,  True,
         True],
       [False,  True,  True, False,  True,  True, False,  True,  True,
         True]])

2.操作布尔数组

x2=np.random.randint(10,size=(3,4))
x2
array([[8, 9, 7, 6],
       [9, 1, 4, 0],
       [8, 9, 1, 6]])
print(x2>5)
np.sum(x2>5)
[[ True  True  True  True]
 [ True False False False]
 [ True  True False  True]]





8
np.all(x2>0)
False
np.any(x2==6)
True
np.all(x2<8,axis=0)
array([False, False,  True,  True])
x2
array([[8, 9, 7, 6],
       [9, 1, 4, 0],
       [8, 9, 1, 6]])
(x2<9)&(x2>5)
array([[ True, False,  True,  True],
       [False, False, False, False],
       [ True, False, False,  True]])
np.sum((x2<9)&(x2>5))
5

3.将布尔数组作为掩码

x2
array([[8, 9, 7, 6],
       [9, 1, 4, 0],
       [8, 9, 1, 6]])
x2>5
array([[ True,  True,  True,  True],
       [ True, False, False, False],
       [ True,  True, False,  True]])
x2[x2>5]
array([8, 9, 7, 6, 9, 8, 9, 6])

花哨的索引

1.一维数组

x=np.random.randint(100,size=10)
x
array([50, 54, 60, 56, 16, 99, 64, 60,  0, 43])

注意:结果的形状与索引数组一致

ind=[2,6,9]
x[ind]
array([60, 64, 43])
ind=np.array([[1,0],
             [2,3]])
x[ind]
array([[54, 50],
       [60, 56]])

2.多维数组

x=np.arange(12).reshape(3,4)
x
array([[ 0,  1,  2,  3],
       [ 4,  5,  6,  7],
       [ 8,  9, 10, 11]])
row=np.array([0,1,2])
col=np.array([1,3,0])
x[row,col]     # (0,1)  (1,3)  (2,0)
array([1, 7, 8])
row[:,np.newaxis]   #列向量
array([[0],
       [1],
       [2]])
x[row[:,np.newaxis],col]
array([[ 1,  3,  0],
       [ 5,  7,  4],
       [ 9, 11,  8]])

其他NumPy通用函数

x=np.random.randint(20,50,size=10)
x
array([41, 28, 48, 35, 38, 22, 42, 46, 26, 25])
  • 产生新的排序数组
np.sort(x)
array([22, 25, 26, 28, 35, 38, 41, 42, 46, 48])
x
array([41, 28, 48, 35, 38, 22, 42, 46, 26, 25])
  • 替换原数组
x.sort()
x
array([22, 25, 26, 28, 35, 38, 41, 42, 46, 48])
  • 获得排序索引
x=np.random.randint(20,50,size=10)
x
array([35, 23, 29, 35, 34, 37, 23, 46, 31, 36])
i=np.argsort(x)
i
array([1, 6, 2, 8, 4, 0, 3, 9, 5, 7], dtype=int64)

最大最小值

x=np.random.randint(20,50,size=10)
x
array([36, 32, 35, 30, 23, 47, 48, 30, 47, 45])
np.max(x)
48
np.min(x)
23
np.argmax(x)
6
np.argmin(x)
4

数值求和求积

x=np.arange(1,6)
x
array([1, 2, 3, 4, 5])
x.sum()
15
np.sum(x)
15
x1=np.arange(6).reshape(2,3)
x1
array([[0, 1, 2],
       [3, 4, 5]])
  • 按行求和
np.sum(x1,axis=1)
array([ 3, 12])
  • 按列求和
np.sum(x1,axis=0)
array([3, 5, 7])
  • 全体求和
np.sum(x1)
15
  • 求积
x
array([1, 2, 3, 4, 5])
x.prod()
120
np.prod(x)
120

中位数、均值、方差、标准差

x=np.random.normal(0,1,size=10000)
import matplotlib.pyplot as plt
plt.hist(x,bins=50)
plt.show()
  • 中位数
np.median(x)
-0.02025749543705074
  • 均值
np.mean(x)
-0.007983776023273992
x.mean()
-0.007983776023273992
  • 方差
x.var()
1.0101942249253268
np.var(x)
1.0101942249253268
  • 标准差
x.std()
1.0050841879789607
np.std(x)
1.0050841879789607
温馨提示:本文最后更新于2024-05-26,若文件或内容有错误或已失效,请在下方留言
© 版权声明
THE END
喜欢就支持一下吧
点赞10赞赏 分享
评论 抢沙发

请登录后发表评论

    暂无评论内容