9

NumPy入门学习笔记(包括详细代码举例和注释)

 3 years ago
source link: https://blog.csdn.net/strivequeen/article/details/112984264
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

NumPy(Numeric Python)是一个用python实现的科学计算的扩展程序库,包括:

  1. 一个强大的N维数组对象Array;
  2. 比较成熟的(广播)函数库;
  3. 用于整合C/C++和Fortran代码的工具包;
  4. 实用的线性代数、傅里叶变换和随机数生成函数。numpy和稀疏矩阵运算包scipy配合使用更加方便。

NumPy 提供了许多高级的数值编程工具,如:矩阵数据类型、矢量处理,以及精密的运算库。专为进行严格的数字处理而产生。多为很多大型金融公司使用,以及核心的科学计算组织如:Lawrence Livermore,NASA用其处理一些本来使用C++,Fortran或Matlab等所做的任务。

1.Numpy基本操作

import numpy as np

1.1 列表转为矩阵

array = np.array([
    [1,3,5],
    [4,6,9]
])

print(array)
[[1 3 5]
 [4 6 9]]

1.2 维度

print('number of dim:', array.ndim)
number of dim: 2

1.3 行数和列数

print('shape:',array.shape)
print('shape:',array.shape[0])
print('shape:',array.shape[1])
shape: (2, 3)
shape: 2
shape: 3

1.4 元素个数

print('size:',array.size)
size: 6

2.Numpy创建array

2.1 一维array创建

# 一维array
a = np.array([2,23,4], dtype=np.int32) # np.int默认为int32
print(a)
print(a.dtype)
[ 2 23  4]
int32

2.2 多维array创建

# 多维array
a = np.array([[2,3,4],
              [3,4,5]])
print(a) # 生成2行3列的矩阵
[[2 3 4]
 [3 4 5]]

2.3 创建全零数组

a = np.zeros((3,4))
print(a) # 生成3行4列的全零矩阵
[[0. 0. 0. 0.]
 [0. 0. 0. 0.]
 [0. 0. 0. 0.]]

2.4 创建全1数据

# 创建全一数据,同时指定数据类型
a = np.ones((3,4),dtype=np.int)
print(a)
[[1 1 1 1]
 [1 1 1 1]
 [1 1 1 1]]

2.5 创建全空数组

# 创建全空数组,其实每个值都是接近于零的数
a = np.empty((3,4))
print(a)
[[0. 0. 0. 0.]
 [0. 0. 0. 0.]
 [0. 0. 0. 0.]]

2.6 创建连续数组

# 创建连续数组
a = np.arange(10,21,2) # 10-20的数据,步长为2
print(a)
[10 12 14 16 18 20]

2.7 reshape操作

# 使用reshape改变上述数据的形状
b = a.reshape((2,3))
print(b)
[[10 12 14]
 [16 18 20]]

2.8 创建连续型数据

# 创建线段型数据
a = np.linspace(1,10,20) # 开始端1,结束端10,且分割成20个数据,生成线段
print(a)
[ 1.          1.47368421  1.94736842  2.42105263  2.89473684  3.36842105
  3.84210526  4.31578947  4.78947368  5.26315789  5.73684211  6.21052632
  6.68421053  7.15789474  7.63157895  8.10526316  8.57894737  9.05263158
  9.52631579 10.        ]

2.9 linspace的reshape操作

# 同时也可以reshape
b = a.reshape((5,4))
print(b)
[[ 1.          1.47368421  1.94736842  2.42105263]
 [ 2.89473684  3.36842105  3.84210526  4.31578947]
 [ 4.78947368  5.26315789  5.73684211  6.21052632]
 [ 6.68421053  7.15789474  7.63157895  8.10526316]
 [ 8.57894737  9.05263158  9.52631579 10.        ]]

3.Numpy基本运算

3.1 一维矩阵运算

# 一维矩阵运算
a = np.array([10,20,30,40])
b = np.arange(4)
print(a,b)
[10 20 30 40] [0 1 2 3]

c = a - b
print(c)
[10 19 28 37]

print(a*b) 
print(a.dot(b))# 若用a.dot(b),则为点乘,各维之和
[  0  20  60 120]
200

# 在Numpy中,想要求出矩阵中各个元素的乘方需要依赖双星符号 **,以二次方举例,即:
c = b**2
print(c)
[0 1 4 9]

# Numpy中具有很多的数学函数工具
c = np.sin(a)
print(c)
[-0.54402111  0.91294525 -0.98803162  0.74511316]

# 布尔型
print(b<2)
[ True  True False False]

a = np.array([1,1,4,3])
b = np.arange(4)
print(a==b)
[False  True False  True]

3.2 多维矩阵运算

a = np.array([[1,1],[0,1]])
b = np.arange(4).reshape((2,2))
print(a)
[[1 1]
 [0 1]]
print(b)
[[0 1]
 [2 3]]

# 多维度矩阵乘法
# 第一种乘法方式:
c = a.dot(b)
print(c)
[[2 4]
 [2 3]]

# 第二种乘法:
c = np.dot(a,b)
print(c)
[[2 4]
 [2 3]]
# 多维矩阵乘法不能直接使用'*'号

a = np.random.random((2,4))
print(a)
[[0.47963593 0.15801515 0.25886847 0.74290887]
 [0.78781928 0.00950545 0.13431407 0.29972804]]
 
print(np.sum(a))
2.8707952592476946
print(np.sum(a,0))  # 对列求和
[1.26745521 0.1675206  0.39318254 1.04263691]
print(np.sum(a,1))  # 对行求和
[1.63942841 1.23136685]

print(np.min(a))
0.009505447212577067
print(np.max(a))
0.7878192846594083

# 如果你需要对行或者列进行查找运算,就需要在上述代码中为 axis 进行赋值。
# 当axis的值为0的时候,将会以列作为查找单元,
# 当axis的值为1的时候,将会以行作为查找单元。
print("sum=",np.sum(a,axis=1))
sum= [1.63942841 1.23136685]
print("min=",np.min(a,axis=0))
min= [0.47963593 0.00950545 0.13431407 0.29972804]
print("max=",np.max(a,axis=1))
max= [0.74290887 0.78781928]

3.3 基本计算

A = np.arange(2,14).reshape((3,4))
print(A)
[[ 2  3  4  5]
 [ 6  7  8  9]
 [10 11 12 13]]
 
# 最小元素索引
print(np.argmin(A)) # 0
# 最大元素索引
print(np.argmax(A)) # 11
# 求整个矩阵的均值
print(np.mean(A)) # 7.5
print(np.average(A)) # 7.5
print(A.mean()) # 7.5
# 中位数
print(np.median(A)) # 7.5

# 累加
print(np.cumsum(A))
[ 2  5  9 14 20 27 35 44 54 65 77 90]
# 累差运算
B = np.array([[3,5,9],
              [4,8,10]])
print(np.diff(B))
[[2 4]
 [4 2]]
 
# 返回数组a中非零元素的索引值数组
C = np.array([[0,5,9],
              [4,0,10]])
# 索引值数组的每一个array均是从一个维度上来描述其索引值。
# 比如,如果a是一个二维数组,则索引值数组有两个array,第一个array从行维度来描述索引值;第二个array从列维度来描述索引值。
print(np.nonzero(B))
(array([0, 0, 0, 1, 1, 1], dtype=int64), array([0, 1, 2, 0, 1, 2], dtype=int64))
print(np.nonzero(C))
(array([0, 0, 1, 1], dtype=int64), array([1, 2, 0, 2], dtype=int64))

# 仿照列表排序
A = np.arange(14,2,-1).reshape((3,4)) # -1表示反向递减一个步长
print(A)
[[14 13 12 11]
 [10  9  8  7]
 [ 6  5  4  3]]

print(np.sort(A))
[[11 12 13 14]
 [ 7  8  9 10]
 [ 3  4  5  6]]

# 矩阵转置
print(np.transpose(A))
print(A.T)
[[14 10  6]
 [13  9  5]
 [12  8  4]
 [11  7  3]]

# clip(Array,Array_min,Array_max) 限制范围函数
# 将Array_min<X<Array_max X表示矩阵A中的数,如果满足上述关系,则原数不变。
# 否则,如果X<Array_min,则将矩阵中X变为Array_min;
# 如果X>Array_max,则将矩阵中X变为Array_max.
print(np.clip(A,5,9))
[[9 9 9 9]
 [9 9 8 7]
 [6 5 5 5]]

4.Numpy索引与切片

4.1 整数索引和切片的基本使用

A = np.arange(3,15)
print(A)
[ 3  4  5  6  7  8  9 10 11 12 13 14]
# 索引
print(A[3]) # 6

B = A.reshape(3,4)
print(B)
[[ 3  4  5  6]
 [ 7  8  9 10]
 [11 12 13 14]]
print(B[2])
[11 12 13 14]
print(B[0][2]) # 5
print(B[0,2]) # 5

# list切片操作
print(B[1,1:3]) # [8 9] 1:3表示1-2不包含3
for row in B:
    print(row)
[3 4 5 6]
[ 7  8  9 10]
[11 12 13 14]

# 如果要打印列,则进行转置即可
for column in B.T:
    print(column)
[ 3  7 11]
[ 4  8 12]
[ 5  9 13]
[ 6 10 14]

# 多维转一维
A = np.arange(3,15).reshape((3,4))
print(A)
[[ 3  4  5  6]
 [ 7  8  9 10]
 [11 12 13 14]]
print(A.flatten())   # flat是一个迭代器,本身是一个object属性
[ 3  4  5  6  7  8  9 10 11 12 13 14]

切片取值方式(对应颜色是取出来的结果):

在这里插入图片描述
在这里插入图片描述

4.2 花式(数组)索引的基本使用

demo_arr = np.empty((4, 4))               # 创建一个空数组
print(demo_arr[0])
[6.23042070e-307 1.89146896e-307 1.37961302e-306 1.05699242e-307]

for i in range(4):
    demo_arr[i] = np.arange(i, i + 4)   # 动态地为数组添加元素
demo_arr
array([[0., 1., 2., 3.],
       [1., 2., 3., 4.],
       [2., 3., 4., 5.],
       [3., 4., 5., 6.]])

demo_arr[[0, 2]]        # 获取索引为[0,2]的元素(0、2行)
array([[0., 1., 2., 3.],
       [2., 3., 4., 5.]])

demo_arr[[1, 3], [1, 2]]     # 获取索引为(1,1)和(3,2)的元素
array([2., 5.])

4.3 布尔型

# 存储学生姓名的数组
student_name = np.array(['Tom', 'Lily', 'Jack', 'Rose'])
student_name
array(['Tom', 'Lily', 'Jack', 'Rose'], dtype='<U4')
# 存储学生成绩的数组
student_score = np.array([[79, 88, 80], [89, 90, 92], [83, 78, 85], [78, 76, 80]])
student_score
array([[79, 88, 80],
       [89, 90, 92],
       [83, 78, 85],
       [78, 76, 80]])

# 对student_name和字符串“Jack”通过运算符产生一个布尔型数组
student_name == 'Jack'
array([False, False,  True, False])

# 将布尔数组作为索引应用于存储成绩的数组student_score,返回的数据是True值对应的行
student_score[student_name=='Jack']
array([[83, 78, 85]])
student_score[student_name=='Jack', :1]
array([[83]])

5.Numpy array合并

5.1 数组合并

A = np.array([1,1,1])
B = np.array([2,2,2])
# vertical stack 上下合并,对括号的两个整体操作。
C = np.vstack((A,B)) 
print(C)  
[[1 1 1]
 [2 2 2]]
print(A.shape,B.shape,C.shape)# 从shape中看出A,B均为拥有3项的数组(数列)
(3,) (3,) (2, 3)
# horizontal stack左右合并
D = np.hstack((A,B))
print(D)
[1 1 1 2 2 2]
print(A.shape,B.shape,D.shape)
(3,) (3,) (6,)
# 对于A,B这种,为数组或数列,无法进行转置,需要借助其他函数进行转置

5.2 数组转为矩阵

print(A[np.newaxis,:]) # [1 1 1]变为[[1 1 1]]
print(A[np.newaxis,:].shape) # (3,)变为(1, 3)
print(A[:,np.newaxis])
[[1]
 [1]
 [1]]

5.3 多个矩阵合并

# concatenate的第一个例子
A = A[:,np.newaxis] # 数组转为矩阵
B = B[:,np.newaxis] # 数组转为矩阵
print(A)
[[1]
 [1]
 [1]]
print(B)
[[2]
 [2]
 [2]]

# axis=0纵向合并
C = np.concatenate((A,B),axis=0)
print(C)
[[1]
 [1]
 [1]
 [2]
 [2]
 [2]]
# axis=1横向合并
C = np.concatenate((A,B),axis=1)
print(C)
[[1 2]
 [1 2]
 [1 2]]

# concatenate的第二个例子
a = b = np.arange(8).reshape(2,4)
print(a)
[[0 1 2 3]
 [4 5 6 7]]

# axis=0多个矩阵纵向合并
c = np.concatenate((a,b),axis=0)
print(c)
[[0 1 2 3]
 [4 5 6 7]
 [0 1 2 3]
 [4 5 6 7]]

# axis=1多个矩阵横向合并
c = np.concatenate((a,b),axis=1)
print(c)
[[0 1 2 3 0 1 2 3]
 [4 5 6 7 4 5 6 7]]

6.Numpy array分割

A = np.arange(12).reshape((3,4))
print(A)
[[ 0  1  2  3]
 [ 4  5  6  7]
 [ 8  9 10 11]]

6.1 等量分割

# 纵向分割 同横向合并的axis
print(np.split(A, 2, axis=1))
# 等价于
print(np.hsplit(A,2)) 
[array([[0, 1],
       [4, 5],
       [8, 9]]), array([[ 2,  3],
       [ 6,  7],
       [10, 11]])]

# 横向分割 同纵向合并的axis
print(np.split(A,3,axis=0))
# 等价于
print(np.vsplit(A,3))
[array([[0, 1, 2, 3]]), array([[4, 5, 6, 7]]), array([[ 8,  9, 10, 11]])]

6.2 不等量分割

print(np.array_split(A,3,axis=1))
[array([[0, 1],
       [4, 5],
       [8, 9]]), array([[ 2],
       [ 6],
       [10]]), array([[ 3],
       [ 7],
       [11]])]

7. copy 与 ‘=’

7.1 ‘=’ 赋值方式会带有关联性

a = np.arange(4)
print(a) # [0 1 2 3]

b = a
c = a
d = b
a[0] = 11
print(a) # [11  1  2  3]
print(b) # [11  1  2  3]
print(c) # [11  1  2  3]
print(d) # [11  1  2  3]
print(b is a) # True
print(c is a) # True
print(d is a) # True

d[1:3] = [22,33]
print(a) # [11 22 33  3]
print(b) # [11 22 33  3]
print(c) # [11 22 33  3]

7.2 copy()赋值方式没有关联性

a = np.arange(4)
print(a) # [0 1 2 3]

b =a.copy() # deep copy
print(b) # [0 1 2 3]

a[3] = 44  # 此时a与b已经没有关联
print(a) # [ 0  1  2 44]
print(b) # [0 1 2 3]

8.广播机制

numpy数组间的基础运算是一对一,也就是a.shape==b.shape,但是当两者不一样的时候,就会自动触发广播机制,如下例子:

from numpy import array
a = array([[ 0, 0, 0],
           [10,10,10],
           [20,20,20],
           [30,30,30]])
b = array([0,1,2])
print(a+b)
[[ 0  1  2]
 [10 11 12]
 [20 21 22]
 [30 31 32]]

# 这里以tile模拟上述操作,来回到a.shape==b.shape情况
# 对[0,1,2]行重复4次,列重复1次
b = np.tile([0,1,2],(4,1))
print(a+b)
[[ 0  1  2]
 [10 11 12]
 [20 21 22]
 [30 31 32]]

只有当两个数组的 trailing dimensions compatible (尾部维度兼容)时才会触发广播,否则报错ValueError: frames are not aligned exception

在这里插入图片描述
在这里插入图片描述

9.常用函数

9.1 np.bincount()

x = np.array([1, 2, 3, 3, 0, 1, 4])
np.bincount(x) # 统计索引出现次数
array([1, 2, 1, 2, 1], dtype=int64) # 索引0出现1次,1出现2次,2出现1次,3出现2次,4出现1次

# 设置weights参数
w = np.array([0.3,0.5,0.7,0.6,0.1,-0.9,1])
np.bincount(x,weights=w)
array([ 0.1, -0.6,  0.5,  1.3,  1. ])
# 计算过程:
# x --->  [1, 2, 3, 3, 0, 1, 4]
# w --->  [0.3,0.5,0.7,0.6,0.1,-0.9,1] 
# 索引 0 出现在x中index=4位置,那么在w中访问index=4的位置即可,w[4]=0.1
# 索引 1 出现在x中index=0与index=5位置,那么在w中访问index=0与index=5的位置即可,然后将两这个加和,计算得:w[0]+w[5]=-0.6

# bincount的另外一个参数为minlength,当所给的bin数量多于实际从x中得到的bin数量后,后面没有访问到的设置为0即可。
np.bincount(x,weights=w,minlength=7)
array([ 0.1, -0.6,  0.5,  1.3,  1. ,  0. ,  0. ])

9.2 np.argmax()

函数原型为:numpy.argmax(a, axis=None, out=None).
函数表示返回沿轴 axis 最大值的索引。

x = [[1,3,3],
     [7,5,2]]
print(np.argmax(x))  
3	# 7最大,索引位置为3(这个索引按照递增顺序)

print(np.argmax(x,axis=0))	# axis=0表示按列操作,也就是对比当前列,找出最大值的索引
[1 1 0]
print(np.argmax(x,axis=1))	# axis=1表示按行操作,也就是对比当前行,找出最大值的索引
[1 0]

# 若碰到重复最大元素,返回第一个最大值索引即可
x = np.array([1, 3, 2, 3, 0, 1, 0])
print(x.argmax()) # 1

9.3 上述合并实例

x = np.array([1, 2, 3, 3, 0, 1, 4])
print(np.argmax(np.bincount(x)))
1
# 计算过程:
# np.bincount(x) = [1, 2, 1, 2, 1]
# 返回第一个最大值的index即可!2的index为1,所以返回1

9.4 求取精度

# 取指定位置的精度
# decimals表示指定保留有效数的位数,当超过5就会进位(此时包含5)
np.around([-0.6,1.2798,2.357,9.67,13], decimals=0)	
array([-1.,  1.,  2., 10., 13.])
np.around([1.2798,2.357,9.67,13], decimals=1)
array([ 1.3,  2.4,  9.7, 13. ])

# -1表示看一位数进位即可。当超过5时候(不包含5),才会进位
np.around([1,2,5,6,56], decimals=-1)
array([ 0,  0,  0, 10, 60])
# -2表示必须看两位,超过50才会进位
np.around([1,2,5,50,56,190], decimals=-2)
array([  0,   0,   0,   0, 100, 200])

# 计算沿指定轴第N维的离散差值
x = np.arange(1 , 16).reshape((3 , 5))
print(x)
[[ 1  2  3  4  5]
 [ 6  7  8  9 10]
 [11 12 13 14 15]]
np.diff(x,axis=1) #默认axis=1
array([[1, 1, 1, 1],
       [1, 1, 1, 1],
       [1, 1, 1, 1]])
np.diff(x,axis=0) 
array([[5, 5, 5, 5, 5],
       [5, 5, 5, 5, 5]])

# 取整
np.floor([-0.6,-1.4,-0.1,-1.8,0,1.4,1.7])
array([-1., -2., -1., -2.,  0.,  1.,  1.])

# 取上限,即找到这个小数的最大整数
np.ceil([1.2,1.5,1.8,2.1,2.0,-0.5,-0.6,-0.3])
array([ 2.,  2.,  2.,  3.,  2., -0., -0., -0.])

# 查找
x = np.array([[1, 0],
       [2, -2],
     [-2, 1]])
print(x)
[[ 1  0]
 [ 2 -2]
 [-2  1]]
# 利用np.where实现小于0的值用0填充吗,大于0的数不变
np.where(x>0,x,0)
array([[1, 0],
       [2, 0],
       [0, 1]])

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK