文章目录
numpy简介
numpy是Python的一种开源数值计算扩展。可以用来存储和处理大型矩阵,比Python自带的嵌套列表要高效的多。numpy也提供了许多高级的数值编程工具。
numpy是Python数据分析必不可少的有力工具!
在使用第三方库之前需要先进行导包:import numpy as np
这里对其取别名为np。
numpy的数组对象
numpy的一个重要特性就是它的数组计算。需要注意的是numpy数组对象中的所有元素类型统一(即一个数组中所有元素类型一致),与强制类型语言相似。
numpy的数组对象支持整体运算,而且效率要高很多。例如:数组对象与一个常数运算或数组对象与另一个数组对象运算
# 数组对象与一个常数运算
arr1 = np.array([1, 2, 3, 4])
print(arr + 1) # 数组中元素与常数运算
# 数组与一个常数逻辑运算
arr2 = np.array([1, 2, 3, 4])
print(arr2 > 3)
# 数组对象与另一个数组对象运算
arr3 = np.array([4, 3, 2, 1])
print(arr1 * arr3) # 两数组对应位置相运算
输出:
[2 3 4 5]
[False False False True]
[4 6 6 4]
产成numpy数组对象方法
1.使用列表产生numpy数组
以列表作为的参数,产生array对象:
lst = [1, 2, 3, 4]
arr = np.array(lst)
在初始化时可以使用dtype
指定数组元素的类型:
lst = [1, 2, 3, 4]
arr = np.array(lst, dtype = 'str')
也可以修改已经初始化好数组对象的类型,使用astype
方法或asarray
方法:
lst = [1, 2, 3, 4]
arr = np.array(lst)
# asarray直接修改指定数组
np.asarray(arr, dtype = 'float')
# astype并非修改原数组,而是返回一个新的数组
arr = arr.astype('str')
print(arr)
2.产生全0或全1数组:
# 生成全0或全1数组
# 全0,默认为浮点数
arr1 = np.zeros(5)
print(arr1)
# 全1,使用dtype修改类型为整型
arr2 = np.ones(5, dtype = 'int')
print(arr2)
输出:
[0. 0. 0. 0. 0.]
[1 1 1 1 1]
3.使用fill
方法修改数组元素:
使用此种方式修改数组元素必须保证修改值的数据类型与原数组类型一致。
例如,原数组为整数类型,统一修改为6(整数类型):
arr = np.array([1, 2, 3, 4, 5])
arr.fill(6)
print(arr) # 输出:[6 6 6 6 6]
注意:类型不一致时会进行强制转化,如:float->int;如果不支持强制类型转化则会报错,如:str->int。
4.生成特殊的数组序列:
(1)生成整数序列arange(a, b, step)
。注意范围为[a, b)左闭右开:
# 类似于range(a, b, step),左闭右开,step是步长
arr = np.arange(1, 10)
# 输出:[1 2 3 4 5 6 7 8 9]、
arr = np.arange(10, 1, -1)
# 输出:[10 9 8 7 6 5 4 3 2]
(2)生成等差数列linspace(a, b, n)
。注意范围为[a, b]左右均包含,n为共多少个数字可以理解为将闭区间分隔为n份:
# 生成[1, 10],共15个数字的等差序列
arr = np.linspace(1, 10, 15)
print(arr)
输出:
[ 1. 1.64285714 2.28571429 2.92857143 3.57142857 4.21428571
4.85714286 5.5 6.14285714 6.78571429 7.42857143 8.07142857
8.71428571 9.35714286 10. ]
(3)生成随机数序列
a.生成范围为[0, 1)(左闭右开)的随机数序列np.random.rand(n, m)
:
# 不填写任何参数时返回一个随机数
num = np.random.rand()
print(num, '\n')
# 填写一个参数n时返回n个随机数构成的数组
arr1 = np.random.rand(10)
print(arr1, '\n')
# 填写两个参数n, m时返回n行m列的随机数数组
arr2 = np.random.rand(2, 3)
print(arr2)
输出:
0.3780761471310673
[0.28653327 0.03327068 0.38612805 0.75801857 0.89595075 0.72235911
0.04731878 0.42461099 0.15136261 0.14024256]
[[0.5203901 0.77576532 0.9085788 ]
[0.07710078 0.25319895 0.34133784]]
b.生成范围为[0, 1)(左闭右开)的服从标准正态分布随机数序列np.random.randn(n, m)
:
# 不填写任何参数时返回一个随机数
num = np.random.randn()
print(num, '\n')
# 填写一个参数n时返回n个随机数构成的数组
arr1 = np.random.randn(10)
print(arr1, '\n')
# 填写两个参数n, m时返回n行m列的随机数数组
arr2 = np.random.randn(2, 3)
print(arr2)
输出:
-0.8298964311982443
[ 0.53170068 -0.19542988 -1.19366799 0.2159826 -1.1726869 2.00576664
-1.23359425 -0.21274355 -0.54825527 1.3430285 ]
[[ 1.0541609 -0.5552323 0.02314327]
[-0.33265642 0.07586351 -1.11465689]]
c.生成范围为[a, b)(左闭右开)的随机整数数序列np.random.randint(a, b, n)
:
# 生成8个[5, 9)之间的随机数
arr = np.random.randint(5, 9, 8)
print(arr)
输出:
[5 7 8 8 5 8 6 6]
numpy数组属性
首先生成一个2行3列的数组对象以便之后的测试:
arr = np.array([[1, 2, 3],
[4, 5, 6]], dtype = 'float')
1.使用dtype
属性查看数组元素的数据类型:
print(arr.dtype) # 输出: float64
2.使用shape
属性查看数组的形状,返回一个元组每个元素代表数组在这一维的元素个数:
print(arr.shape) # 输出:(2, 3)
3.使用size
属性查看数组中元素的个数:
print(arr.size) # 输出:6
4.使用ndim
属性查看数组的维度:
print(arr.ndim) # 输出:2
numpy数组的索引和切片
一般的索引与切片操作与列表相同,这里着重说明与列表不同的操作!
首先生成一个4行4列的数组对象以便之后的测试:
arr = np.array([[1, 2, 3, 4],
[5, 6 ,7, 8],
[9, 10, 11, 12],
[13, 14, 15, 16]], dtype = 'float')
numpy数组的索引
a.使用,
隔开的索引方式:
# 相当于使用逗号隔开了行和列
print(arr[0, 0], arr[3, 3])
输出:
1.0
16.0
b.使用整数列表的索引方式(只适合一维数组)。取出列表中值所对应的下标的元素:
arr1 = np.array([1, 2, 3, 4, 5])
# 取出列表中值所对应下标的元素
idx = [0, 1, -1]
print(arr1[idx])
输出:
[1 2 5]
c.使用布尔numpy数组的索引方式。bool数组的shape
属性必须与要进行索引的数组shape
一致,因为这种索引方式采用一一对应的方式来取出元素,即对应元素为True则取出:
arr1 = np.array([[1, 2],
[3, 4]])
# 取出对应为True位置的元素
idx = np.array([[1, 1],
[0, 1]], dtype = 'bool')
print(arr1[idx])
输出:
[1 2 4]
numpy数组的切片
注意:numpy数组的切片应用的是引用机制,不会为切片分配内存且容易改变原数组内容,可以使用深拷贝来得到分配了内存的切片。
a.切片格式数组名[a:b:step1, s:e:step2]
(以常用的二维数组为例)
其中,a和s代表每一维的起点,b和e代表每一维的终点(不包括b和e,因为左闭右开),step1和step2分别为每一维的步长(步长可以为负,同列表步长可以省略默认为1)。
# 切出所有行,[1, 4)列
print(arr[:, 1:4])
# 反向切出所有行和列,相当于转置
print(arr[::-1, ::-1])
输出:
# 切出所有行,[1, 4)列
[[ 2. 3. 4.]
[ 6. 7. 8.]
[10. 11. 12.]
[14. 15. 16.]]
# 反向切出所有行和列,相当于转置
[[16. 15. 14. 13.]
[12. 11. 10. 9.]
[ 8. 7. 6. 5.]
[ 4. 3. 2. 1.]]
b.使用元组指定行和列,格式为数组名[元组, s:e:step2]
(元组可以作用于行也可以作用于列,这里格式使用行)
# 要1, 2, 3行所有列元素
print(arr[(1, 2, 3), :])
# 要1, 2, 3列所有行元素
print(arr[: ,(1, 2, 3)])
输出:
# 要1, 2, 3行所有列元素
[[ 5. 6. 7. 8.]
[ 9. 10. 11. 12.]
[13. 14. 15. 16.]]
# 要1, 2, 3列所有行元素
[[ 2. 3. 4.]
[ 6. 7. 8.]
[10. 11. 12.]
[14. 15. 16.]]
注意:使用两个元组行切片,表示切出以两个元组对应位置元素为下标的数组元素:
# 切出三个元素下标分别为:(1, 0), (2, 1), (3, 2)
print(arr[(1, 2, 3), (0, 1, 2)])
输出:
[ 5. 10. 15.]
where语句
where()
语句返回数组中非零元素的索引
一维数组:
arr1 = np.array([0, 1, 2, 0, 3])
print(np.where(arr1))
输出:
在这里插入代码片
二维数组:
arr2 = np.array([[1, 0, 3],
[0, 5, 0]])
# 返回两个数组,第一个包含行下标, 第二个包含列下标
idx1, idx2 = np.where(arr2)
for i1, i2 in zip(idx1, idx2):
print(i1, i2)
输出:
0 0
0 2
1 1
多维数组操作
改变数组形状
首先初始化一个数组对象:
arr = np.arange(6)
a.通过reshape()
方法返回一个新数组:
print(arr.reshape(2, 3))
输出:
[[0 1 2]
[3 4 5]]
b.通过修改shape
属性直接修改原数组:
arr.shape = 2,3
print(arr)
输出:
[[0 1 2]
[3 4 5]]
矩阵转置
首先初始化一个数组对象:
arr = np.arange(6)
a.使用成员变量T
获取转置数组:
print(arr.T)
b.使用transpose()
方法获取转置数组:
print(arr.transpose())
两种方式均输出矩阵的转置:
[[1 4]
[2 5]
[3 6]]
数组拼接
使用concatenate((a0, a1,...,an), axis = 0)
将数组拼接起来。默认按照列(axis = 0,即第一维)的方式,即上下方向进行拼接,可以修改axis
的取值按照其它维度拼接。
首先,初始化用来测试的数组:
arr1 = np.array([[1, 2, 3],
[4, 5, 6]])
arr2 = np.array([[7, 8, 9],
[10, 11, 12]])
a.纵向拼接
# 纵向拼接
print(np.concatenate((arr1, arr2)))
输出:
[[ 1 2 3]
[ 4 5 6]
[ 7 8 9]
[10 11 12]]
b.横向拼接
# 横向拼接
print(np.concatenate((arr1, arr2), axis=1))
输出:
[[ 1 2 3 7 8 9]
[ 4 5 6 10 11 12]]
数组堆叠
首先,初始化用来测试的数组:
arr1 = np.array([[1, 2, 3],
[4, 5, 6]])
arr2 = np.array([[7, 8, 9],
[10, 11, 12]])
a.纵向堆叠,使用numpy内置函数vstack()
:
# 纵向堆叠,与一维拼接作用相似
print(np.vstack((arr1, arr2)))
输出:
[[ 1 2 3]
[ 4 5 6]
[ 7 8 9]
[10 11 12]]
b.横向堆叠,使用numpy内置函数hstack()
:
# 横向堆叠,与二维拼接作用相似
print(np.hstack((arr1, arr2)))
输出:
[[ 1 2 3 7 8 9]
[ 4 5 6 10 11 12]]
c.z轴方向堆叠(三维堆叠),使用numpy内置函数dstack()
:
# z轴堆叠
print(np.dstack((arr1, arr2)))
输出:
[[[ 1 7]
[ 2 8]
[ 3 9]]
[[ 4 10]
[ 5 11]
[ 6 12]]]
numpy常用内置函数
排序
a.sort()
方法会返回一个新的经过排序的数组对象:
# 生成随机数数组
arr = np.random.rand(6)
# 排序,返回一个新的数组对象
print(np.sort(arr))
输出:
[0.01400336 0.08577747 0.19896884 0.32283748 0.38470602 0.55287548]
b.argsort()
方法会返回从小到大排列在数组中索引的位置:
arr = np.array([4, 2, 7, 5, 9, 0])
print(np.argsort(arr))
输出:
[5 1 0 3 2 4] # 表明:最小的在索引为5的位置,最大的在索引为4的位置
求和、最值和绝对值
首先生成一个数组对象以便之后测试:
arr = np.array([1, 3, 5, 7, 9])
arr1 = np.array([9, 7, 5, 3, 1])
a.使用sum()
方法求和:
# 求和
print(np.sum(arr)) # 或arr.sum(),效果是一样的。输出25
b.最大值、最小值和绝对值
# 最大值
print(np.max(arr)) # 或arr.max(),效果是一样的。输出9
# 最小值
print(np.min(arr)) # 或arr.min(),效果是一样的。输出1
# 绝对值
print(np.abs(arr)) # 对所有元素取绝对值
中位数和累加和
中位数median()
,累加和cumsum()
arr = np.array([1, 3, 5, 7, 9])
# 中位数
print(np.median(arr))
# 累加和
print(np.cumsum(arr))
输出:
5.0
[ 1 4 9 16 25]
标准差
使用std()
方法:
# 标准差
print(np.std(arr)) # 或arr.std(),效果是一样的。输出2.8284271247461903
协方差矩阵
使用cov()
方法:
# 协方差矩阵
print(np.cov(arr, arr1))
输出:
[[ 10. -10.]
[-10. 10.]]