官方文档
官方文档链接地址:
https://numpy.org/devdocs/user/quickstart.html
导入库
import numpy as np
1-数组的创建
列表创建数组
a1 = np.array([1,2,3])
a1
array([1, 2, 3])
元组创建数组
a2 = np.array((1,2,3))
a2
array([1, 2, 3])
字符串创建数组
a3 = np.array('123')
a3
array('123', dtype='<U3')
np.zeros()
a4 = np.zeros(3)
a4
array([0., 0., 0.])
np.ones()
a5 = np.ones(3)
a5
array([1., 1., 1.])
np.arange()
a6 = np.arange(1, 10, 2)
a6
array([1, 3, 5, 7, 9])
np.linspace()
a7 = np.linspace(1, 10, num=5)
a7
array([ 1. , 3.25, 5.5 , 7.75, 10. ])
np.empty()
a8 = np.empty(2)
a8
array([ 1., 10.])
2-指定数据类型
x = np.ones(2, dtype=np.int64)
x
array([1, 1], dtype=int64)
3-查看数据类型
● type()查看数据类型
type(arr)
numpy.ndarray # 表示多维数组
● arr.dtype # 查看数组的数据类型
arr = np.arange(1,5)
arr.dtype
dtype('int32')
注意
● np.array()会自动推断生成数组的数据类型
4-指定数组的数据类型
● numpy.array(object,dtype=None)
○ 创建数组时通过dtype直接指定
import numpy as np
arr = np.array([1,2,3],dtype='f8')
arr.dtype
● arr.astype(dtype) # 修改数组数据类型
import numpy as np
arr = np.array([1,2,3])
arr = arr.astype(np.float32)
arr.dtype
5-查看数组形状,维度
arr.ndim
查看数组的维度,返回值为整数
arr1 = np.arange(10)
np.ndim(arr1)
1
arr2 = np.array([[1,2,3],[4,5,6]])
np.ndim(arr2)
2
arr.shape
查看数组的,返回值为元组
arr3 = np.arange(15)
np.shape(arr3)
(15,)
arr4 = np.array([[1,2,3],[4,5,6]])
np.shape(arr4)
(2, 3)
arr5 = np.array([[[1,2,3],[4,5,6]],[[7,8,9],[10,11,12]]])
arr5.shape
(2, 2, 3)
6-重塑数组的形状
● reshape 修改后结果返回 不会影响原数据
● resize 直接作用于原数据
a1 = np.random.randint(0,10,size=(3,4))
a1
array([[7, 0, 6, 9],
[9, 7, 6, 9],
[1, 0, 1, 8]])
# 修改后结果返回 不会影响原数据
a2 = a1.reshape((2,6))
a2
array([[7, 0, 6, 9, 9, 7],
[6, 9, 1, 0, 1, 8]])
a1
array([[7, 0, 6, 9],
[9, 7, 6, 9],
[1, 0, 1, 8]])
# 直接作用于原数据
a1.resize((2,6))
a1
array([[7, 0, 6, 9, 9, 7],
[6, 9, 1, 0, 1, 8]])
7-重塑维度
一维转多维
● arr.reshape(shape,order=“C”)
○ shape为数组重塑形状
○ order表示重塑方向
■ C顺序(行方向)重塑
■ F顺序(列方向)重塑
import numpy as np
arr6 = np.arange(6)
arr6 = arr6.reshape(2,3)
arr6
array([[0, 1, 2],
[3, 4, 5]])
多维转一维
● arr.flatten() 不会影响原数据
● arr.ravel() 会影响原数据
arr7 = np.array([[[1,2,3],[4,5,6]],[[7,8,9],[10,11,12]]])
arr7 = arr7.flatten()
arr7
array([ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12])
arr8 = np.array([[[1,2,3],[4,5,6]],[[7,8,9],[10,11,12]]])
arr8 = arr8.ravel()
arr8
array([ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12])
x = np.array([[1,2,3],[4,5,6],[7,8,9],[10,11,12]])
x
array([[ 1, 2, 3],
[ 4, 5, 6],
[ 7, 8, 9],
[10, 11, 12]])
x.flatten()[1] = 100
x
array([[ 1, 2, 3],
[ 4, 5, 6],
[ 7, 8, 9],
[10, 11, 12]])
x.ravel()[1]=100
x
array([[ 1, 100, 3],
[ 4, 5, 6],
[ 7, 8, 9],
[ 10, 11, 12]])
数组转置与换轴
● arr.transpose() # 转置
arr9 = np.array([[1,2,3],[4,5,6],[7,8,9],[10,11,12]])
arr9
array([[ 1, 2, 3],
[ 4, 5, 6],
[ 7, 8, 9],
[10, 11, 12]])
arr9.transpose()
array([[ 1, 4, 7, 10],
[ 2, 5, 8, 11],
[ 3, 6, 9, 12]])
● arr.T # 转置
arr10 = np.array([[1,2,3],[4,5,6],[7,8,9],[10,11,12]])
arr10.T
array([[ 1, 4, 7, 10],
[ 2, 5, 8, 11],
[ 3, 6, 9, 12]])
● arr.swapaxes() # 换轴
arr11 = np.ones((2,3,4,5,6))
np.swapaxes(arr11, 3, 1).shape
(2, 5, 4, 3, 6)
np.swapaxes(arr11, 2,0).shape
(4, 3, 2, 5, 6)
8-数组的操作
8-1 数组的索引
一维和列表的索引差不多
arr1 = np.arange(10)
arr1
array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
arr1[0]
0
arr1[-1]
9
二维数组的索引
arr2 = np.arange(10).reshape(2,5)
arr2
array([[0, 1, 2, 3, 4],
[5, 6, 7, 8, 9]])
arr2[1][1] # 第一个[1]表示第二行,第二个[2]表示第二列
6
arr2[1,1] # 第一个是行,第二个是列
6
arr2[:,2] # 第一个是行,第二个是列
array([2, 7])
布尔索引
a3
array([[ 0, 1, 2, 3, 4, 5],
[ 6, 7, 8, 9, 10, 11],
[12, 13, 14, 15, 16, 17],
[18, 19, 20, 21, 22, 23]])
a3 < 10
array([[ True, True, True, True, True, True],
[ True, True, True, True, False, False],
[False, False, False, False, False, False],
[False, False, False, False, False, False]])
a3[a3<10]
array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
~(a3<10)
array([[False, False, False, False, False, False],
[False, False, False, False, True, True],
[ True, True, True, True, True, True],
[ True, True, True, True, True, True]])
a3[~(a3<10)]
array([10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23])
a3[(a3>10) & (a3<20)]
array([11, 12, 13, 14, 15, 16, 17, 18, 19])
where索引改值
a4 = np.arange(10).reshape(2,5)
a4
array([[0, 1, 2, 3, 4],
[5, 6, 7, 8, 9]])
arr = np.where(a4<5, 1, 0) # 如果小于5就改为1,否则改为0
arr
array([[1, 1, 1, 1, 1],
[0, 0, 0, 0, 0]])
8-2 切片
a3 = np.arange(0,24).reshape((4,6))
a3
array([[ 0, 1, 2, 3, 4, 5],
[ 6, 7, 8, 9, 10, 11],
[12, 13, 14, 15, 16, 17],
[18, 19, 20, 21, 22, 23]])
# 连续切片
a3[:2]
array([[ 0, 1, 2, 3, 4, 5],
[ 6, 7, 8, 9, 10, 11]])
a3[:2,:2]
array([[0, 1],
[6, 7]])
# 不连续切片
a4 = np.arange(10)
a4
array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
a4[0: 6: 2]
array([0, 2, 4])
8-3 堆叠数组
a1 = np.array([[1,1], [2,2]])
a1
array([[1, 1],
[2, 2]])
a2 = np.array([[3,3], [4,4]])
a2
array([[3, 3],
[4, 4]])
垂直堆叠 np.vstack()
np.vstack((a1,a2))
array([[1, 1],
[2, 2],
[3, 3],
[4, 4]])
水平堆叠 np.hstack()
np.hstack((a1,a2))
array([[1, 1, 3, 3],
[2, 2, 4, 4]])
8-4 拆分数组
a3 = np.arange(1, 25).reshape(2, 12)
a3
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]])
np.hsplit()
# 拆分为三个形状相等的数组
np.hsplit(a3, 3)
[array([[ 1, 2, 3, 4],
[13, 14, 15, 16]]), array([[ 5, 6, 7, 8],
[17, 18, 19, 20]]), array([[ 9, 10, 11, 12],
[21, 22, 23, 24]])]
# 在第三列和第四列之后拆分数组
np.hsplit(a3, (3,4))
[array([[ 1, 2, 3],
[13, 14, 15]]), array([[ 4],
[16]]), array([[ 5, 6, 7, 8, 9, 10, 11, 12],
[17, 18, 19, 20, 21, 22, 23, 24]])]
8-5 深浅复制
浅复制 np.view()
a4 = np.array([[1,2,3], [4,5,6]])
a4
array([[1, 2, 3],
[4, 5, 6]])
a4.view()[0,1] = 99
a4
array([[ 1, 99, 3],
[ 4, 5, 6]])
深复制 np.copy()
a5 = np.array([[1,2,3], [4,5,6]])
a5
array([[1, 2, 3],
[4, 5, 6]])
a5.copy()[0,1] = 100
a5
array([[1, 2, 3],
[4, 5, 6]])
8-6 数组的运算
加法、减法、乘法、除法等
data = np.array([22, 44])
data
array([22, 44])
ones = np.array([2, 4])
ones
array([2, 4])
# 加法
data + ones
array([24, 48])
# 减法
data - ones
array([20, 40])
# 乘法
data * ones
array([ 44, 176])
# 除法
data / ones
array([11., 11.])
# 整除
data // ones
array([11, 11], dtype=int32)
# 取模
data % ones
array([0, 0], dtype=int32)
求和 sum()
# 一维数组求和 sum()
a = np.array([1,2,3,4])
a.sum()
10
# 二维数组求和 sum(axis)
arr = np.array([[1,2,3], [4,5,6]])
arr.sum(axis=0) # axis=0表示各个列上的求和
array([5, 7, 9])
arr.sum(axis=1) # axis=1表示各个行上的求和
array([ 6, 15])
求最大值 max()
# 一维数组求最大值 max()
a = np.array([1,2,3,4])
a.max()
4
# 二维数组求最大值 max(axis)
arr = np.array([[1,2,3], [4,5,6]])
arr.max(axis=0) # axis=0表示各个列上的求最大值
array([4, 5, 6])
arr.max(axis=1) # axis=1表示各个行上的求最大值
array([3, 6])
求最小值 min()
# 一维数组求最小值 min()
a = np.array([1,2,3,4])
a.min()
1
# 二维数组求最大值 min(axis)
arr = np.array([[1,2,3], [4,5,6]])
arr.min(axis=0) # axis=0表示各个列上的求最小值
array([1, 2, 3])
arr.min(axis=1) # axis=1表示各个行上的求最小值
array([1, 4])
9-矩阵
创建矩阵
a = np.matlib.empty((2,2))
a
matrix([[1.23729840e-311, 3.21450328e+164],
[1.85692977e+216, 1.99392236e-077]])
type(a)
numpy.matrix
a = np.matlib.zeros((2,2))
a
matrix([[0., 0.],
[0., 0.]])
a = np.matlib.ones((2,2))
a
matrix([[1., 1.],
[1., 1.]])
a = np.matlib.eye(2)
a
matrix([[1., 0.],
[0., 1.]])
mat = np.matrix('1 2;3 4') # 传入字符串,空格代表元素,分号(;)代表第二行数据
mat
matrix([[1, 2],
[3, 4]])
矩阵的一些方法
mat = np.matrix('1 2;3 4') # 传入字符串,空格代表元素,分号(;)代表第二行数据
mat
matrix([[1, 2],
[3, 4]])
# 矩阵的转置
mat.T
matrix([[1, 3],
[2, 4]])
# 逆矩阵
mat.I
matrix([[-2. , 1. ],
[ 1.5, -0.5]])
10-计数
一维数组
# 出现哪些数(相当于返回去重后的结果)
a = np.array([11, 11, 12, 13, 14, 15, 16, 17, 12, 13, 11, 14, 18, 19, 20])
np.unique(a)
array([11, 12, 13, 14, 15, 16, 17, 18, 19, 20])
# 第一次出现的索引
unique_values, indices_list = np.unique(a, return_index=True)
indices_list
array([ 0, 2, 3, 4, 5, 6, 7, 12, 13, 14], dtype=int64)
# 出现的次数
unique_values, occurrence_count = np.unique(a, return_counts=True)
occurrence_count
array([3, 2, 2, 2, 1, 1, 1, 1, 1, 1], dtype=int64)
二维数组
注意:如果未传递 axis 参数,则 2D 数组将被拼合。
# 出现哪些数(相当于返回去重后的结果)
a_2d = np.array([[1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12], [1, 2, 3, 4]])
np.unique(a_2d)
array([ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12])
# 出现的数(指定行)
np.unique(a_2d, axis=0)
array([[ 1, 2, 3, 4],
[ 5, 6, 7, 8],
[ 9, 10, 11, 12]])
# 出现的数(指定列)
np.unique(a_2d, axis=1)
array([[ 1, 2, 3, 4],
[ 5, 6, 7, 8],
[ 9, 10, 11, 12],
[ 1, 2, 3, 4]])
# 获取唯一行,索引位置和出现次数,出现的次数
unique_rows, indices, occurrence_count = np.unique(a_2d, axis=0, return_counts=True, return_index=True)
# 出现的行
unique_rows
array([[ 1, 2, 3, 4],
[ 5, 6, 7, 8],
[ 9, 10, 11, 12]])
# 第一次的出现的行索引
indices
array([0, 1, 2], dtype=int64)
# 出现的次数
occurrence_count
array([2, 1, 1], dtype=int64)
11-反转数组
一维数组
arr = np.array([1, 2, 3, 4, 5, 6, 7, 8])
np.flip(arr)
array([8, 7, 6, 5, 4, 3, 2, 1])
二维数组
arr_2d = np.array([[1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12]])
arr_2d
array([[ 1, 2, 3, 4],
[ 5, 6, 7, 8],
[ 9, 10, 11, 12]])
# 行和列都反转
np.flip(arr_2d)
array([[12, 11, 10, 9],
[ 8, 7, 6, 5],
[ 4, 3, 2, 1]])
# 仅反转行
np.flip(arr_2d, axis=0)
array([[ 9, 10, 11, 12],
[ 5, 6, 7, 8],
[ 1, 2, 3, 4]])
# 仅反转列
np.flip(arr_2d, axis=1)
array([[ 4, 3, 2, 1],
[ 8, 7, 6, 5],
[12, 11, 10, 9]])
# 仅反转某一行
np.flip(arr_2d[1])
array([8, 7, 6, 5])
12-随机数
# 生成一个随机数 [0,1)
np.random.random()
0.43142764744708606
# 生成一个二维的随机数组
np.random.random((3,4))
array([[0.69806947, 0.69508169, 0.95153794, 0.45973527],
[0.80967495, 0.04138477, 0.82565653, 0.14240804],
[0.33931844, 0.09634759, 0.44489129, 0.46498501]])
# 指点范围生成二维数组 [100,200)
np.random.randint(100,200, size=(3,4)) # size指定二维数组的形状,这里指的是3行4列
array([[124, 128, 154, 154],
[194, 100, 126, 108],
[106, 174, 187, 130]])
# 生成均值为0,标准差为1,正态分布的随机数组
np.random.randn(2,3)
array([[ 0.69817353, 0.32590051, 0.19232617],
[-0.48887634, -0.90264261, 0.61403314]])
# 生成均值为4,方差为5,正态分布的随机数组
np.random.normal(4,5, size=(3,5))
array([[ 5.05861337, 6.12297642, 8.4951344 , -1.4410977 , 2.88279346],
[-2.11900587, 10.49810098, 4.6205391 , -4.2484987 , 9.87552727],
[ 0.99644726, 2.36295249, -3.82889728, 13.46392344, 1.19333849]])
# 对一个数组随机排序
np.random.seed(1)
arr = np.random.randint(100,200, size=(3,4))
arr
array([[137, 112, 172, 109],
[175, 105, 179, 164],
[116, 101, 176, 171]])
np.random.shuffle(arr) # 改变原数组
arr
array([[137, 112, 172, 109],
[116, 101, 176, 171],
[175, 105, 179, 164]])
x = np.random.permutation(arr) # 不改变原数组
x
array([[116, 101, 176, 171],
[175, 105, 179, 164],
[137, 112, 172, 109]])
arr
array([[137, 112, 172, 109],
[116, 101, 176, 171],
[175, 105, 179, 164]])
# 抽取数据
data = [4,45,48,456,489,1212,821,5812,1845,646]
np.random.choice(data, size=(2,3))
array([[ 48, 489, 5812],
[5812, 646, 45]])
13-数组的广播机制
a = np.array([[ 0, 5, 10, 15, 20, 25],[30, 35, 40, 45, 50, 55]])
b = np.array([0, 1, 2, 3, 4, 5])
c = np.array([[10],[20]])
d = 100
a+b # 纵向广播
array([[ 0, 6, 12, 18, 24, 30],
[30, 36, 42, 48, 54, 60]])
a+c # 横向广播
array([[10, 15, 20, 25, 30, 35],
[50, 55, 60, 65, 70, 75]])
a+d # 纵向,横向都广播
array([[100, 105, 110, 115, 120, 125],
[130, 135, 140, 145, 150, 155]])
14-将条件逻辑作为数组操作
numpy.where()函数是三元表达式 x if condition else y 的向量化版本。
● np.where(condition, [x, y]) # 当满足条件,执行x,否则执行y
arr = np.arange(16).reshape(4,4)
arr1 = np.where(arr<10,0,10)
arr1
15-NaN与inf
nan与inf介绍
nan:not a number 表示不是一个数字,属于浮点类。
inf:np.inf 表示正无穷,-np.inf表示负无穷,属于浮点类。
NaN特点
● nan与inf都是float类型
c = np.nan
c
type(c) # float
d = np.inf
d
type(d) # float
● 两个nan是不相等的
○ 该特性可以用来判断nan的个数
■ np.count_nonzero() 计算非零的个数
■ np.isnan() 判断数组元素是否是NaN,返回为bool值
np.nan == np.nan # False
● np.nan与任何数值计算都是nan
np.arange([2,np.nan,3])+100 # arry([102,nan,103])
也正因为,np.nan与任何值计算都是nan所以在运算时,会带来较大的误差。一般我们都会将其处理掉。
如何处理nan
直接删除缺失值所在行,但是当数据量较小时,这样处理会有影响整体的数据。更优雅的做法,是当求和时,将np.nan处理为0;当求均值时,将np.nan处理为非nan的均值。
16-random模块
np.random为我们提供了许多获取随机数的函数。其实是python内置random模块进行的封装。
参考网址:https://numpy.org/doc/stable/reference/random/legacy.html#numpy.random.RandomState
np.random.seed
用于指定随机数生成时所用算法开始的整数值,如果使用相同的seed()值,则每次生成的随即数都相同,如果不设置这个值,则系统根据时间来自己选择这个值,此时每次生成的随机数因时间差异而不同。一般没有特殊要求不用设置。以下代码:
np.random.seed(1)
print(np.random.rand())
np.random.rand
生成一个值为[0,1)之间的数组,形状由参数指定,如果没有参数,那么将返回一个随机值。示例代码如下
data = np.random.rand() #生成一个0-1之间的随机数
np.random.randn
生成均值(μ)为0,标准差(σ)为1的标准正态分布的值。示例代码如下:
data = np.random.randn(2,3) #生成一个2行3列的数组,数组中的值都满足标准正太分布
np.random.randint
生成指定范围内的随机数,并且可以通过size参数指定维度。示例代码如下
data = np.random.randint(10,size=(3,5)) #生成值在0-10之间,3行5列的数组
np.random.choice
从一个列表或者数组中,随机进行采样。或者是从指定的区间中进行采样,采样个数可以通过参数指定
data = np.arange(100)
res = np.random.choice(data,size=(2,3)) #从data中随机采样,生成2行3列的数组
np.random.shuffle
把原来数组的元素的位置打乱。
a = np.arange(10)
np.random.shuffle(a) #将a的元素的位置都会进行随机更换
17-常用函数
一元函数
# 有正数 也有 负数
arr = np.random.uniform(-10,10,size=(3,5))
arr
# 求绝对值
np.abs(arr)
np.rint(4.4) # 四舍
np.rint(4.5) # 五舍
np.rint(4.6) # 六入
np.rint(5.5) # 五成双
二元函数
np.add(arr,arr) # 加法运算
arr[np.logical_and(arr>0,arr<5)] # 取出arr中 >0 并且 <5 的数
聚合函数
a1 = np.arange(12).reshape(3,4)
np.sum(a1) # 全部相加
np.sum(a1,axis=0) # 计算0轴的累和
np.sum(a1,axis=1) # 计算1轴方向的累和
18-数组的线性代数运算
A = {
x - 2y + z = 0
2y - 8z = 8
-4x + 5y + 9z = -9
}
A = np.mat("1 -2 1;0 2 -8;-4 5 9")
A
matrix([[ 1, -2, 1],
[ 0, 2, -8],
[-4, 5, 9]])
B = np.array([0,8,-9])
B
array([ 0, 8, -9])
r = np.linalg.solve(A,B)
r
array([29., 16., 3.])
19-文件读写保存操作
● np.savetxt() 保存为文件
● loadtxt() 加载文件
# 创建数组
csv_arr = np.array([1, 2, 3, 4, 5, 6, 7, 8])
csv_arr
# 保存
np.savetxt('new_file.csv', csv_arr, fmt='%d')
np.loadtxt('new_file.csv')
array([1., 2., 3., 4., 5., 6., 7., 8., 9.])
20-拓展:Scipy
● 数学计算
● 科学计算
● 工程计算
他们都依赖numpy
例1:物理和数学的常数
from scipy.constants import pi,c,G,g
pi
3.141592653589793
c
299792458.0
G
6.67408e-11
g
9.80665
例2:线性代数
from scipy import linalg
a = np.array([[1, -2, 1],[0, 2, -8],[-4, 5, 9]])
b = np.array([0,8,-9])
linalg.solve(a,b)
array([29., 16., 3.])
例3:图像处理
from scipy import ndimage
import matplotlib.image as mpimg
import matplotlib.pyplot as plt
a = mpimg.imread('1.jpg')
b = ndimage.rotate(a,60)
plt.imshow(b)
plt.show()