L:python的Numpy模块(存取数组元素,数组运算,排序,随机函数)

简介

NumPy(Numerical Python)是一个开源Python科学计算库,是Python生态圈最重要的底层支持库,支持快速的数组运算,比纯Python代码快得多,因为它底层使用到c来写。NumPy是在Python中进行数据分析、机器学习、人工智能开发的必备工具,是理解学习很多Python工具包的基础。
安装 : pip install numpy # Anaconda已包含np,无需安装。

numpy数组和 list列表运算时间对比示例
import  numpy  as  np			# 引入惯例, 后续都用  np
lst = list(range(1000000))		# 列表
ar = np.arange(1000000)		# np数组
In: %timeit   lst2 = [x*2  for  x  in  lst]
80.8 ms ± 438 µs per loop		# 列表耗时
In: %timeit   ar2 = ar * 2
1.96 ms ± 34.7 µs per loop		# np数组耗时
注:%魔术命令只能在IPython对话窗口运行,不能放入.py程序中。

数组对象特性

x = np.array((90, 85, 80))     	# 成绩
w = np.array((0.4, 0.4, 0.2))  	# 权重
np.mean(x)	#求平均值
np.average(x, weights=w)  	# 按权重求均值
np.sum(x * w) / np.sum(w) 	# 自行按权重求均值,(x*w)会对应的元素相乘

In: b = np.array((10, 9.5, 10.2, 11, 10.8, 10.6, 11.2))   # 收盘价 
In: np.diff(b)   			# 差值,   也可写为   b[1:]  -  b[:-1] ,这样写就是后面一个元素减去前面一个元素
Out: array([-0.5,  0.7,  0.8, -0.2, -0.2,  0.6])
In: ret = np.diff(b) / b[:-1]   	# 涨跌率
Out: array([-0.05,  0.07,  0.08, -0.02, -0.02,  0.06])
In: np.where(ret>0)		# 正收益是哪几天
Out:(array([1, 2, 5], dtype=int64),) 
In: np.__version__     # 版本号'1.16.5',一般的软件包都有
# arange产生6个数,reshape重设为 2x3 数组
In: b = np.arange(6).reshape(2, 3)
In: type(b)  	#  numpy.ndarray
# 数组对象的各种特性
In: b.ndim     	# 数组维度  2
In: b.size       	# 数组中的元素个数 6,   和len(b) 不同,len(b)显示的是数组行数
In: b.shape   	# 数组形状 (2, 3)
In: b.dtype    	# 数组元素的数据类型  dtype('int32')
In: b.itemsize	# 单个元素所需存储字节数  4
In: b.nbytes	# 整个数组所需存储字节数 24  , 即 size * itemsize

生成数组的五种方法

#使用array()/arange()生成数组
In:b = np.array((1, 2, 3, 4)) # 一维
Out: array([1, 2, 3, 4])
In:b = np.arange(1, 5)   	# np.arange(1,5,0.5) 小数步长
Out: array([1, 2, 3, 4])
In: np.repeat(b,2)    	# 将元素重复2次
Out:array([1, 1, 2, 2, 3, 3, 4, 4])
In: np.tile(b, 3)  		# 将数组重复3次
Out: array([1, 2, 3, 4, 1, 2, 3, 4, 1, 2, 3, 4])
In:b = np.array([[1, 2] , [3, 4], [5, 6]])       # 二维
In:b=np.arange(4000).reshape(4, 1000) # 二维
#可以使用ones()/zeros()/linspace()生成数组。
np.ones(5) 		# 生成含有5个元素的一维全1数组
np.ones((2, 3))    	# 生成2x3的二维全1数组
np.zeros((2, 3)) 	# 生成2x3的二维全0数组
np.ones_like(b)      	# 生成维数和b相同的全1数组
np.eye(3) 		# 单位矩阵数组

np.linspace(1, 2, 5)  			# [1, 2] 间均匀分布5个数
Out: array([1.  , 1.25, 1.5 , 1.75, 2.  ]) 	# 默认含终值
np.linspace(1, 2, 5, endpoint=False)   	# 不含终值
Out:array([1. , 1.2, 1.4, 1.6, 1.8])

x = np.linspace(0, np.pi, 7)  # [0, π] 间均匀分布7个数, 即间隔 30度
np.sin(x)    	#  np.round(np.sin(x), 2)
#使用随机函数生成数组。
ar = np.random.rand(3,4) 		# 3x4数组, [0, 1)内均匀分布小数
np.set_printoptions(precision=3)   	# 小数部分显示3位

np.random.randint(1,100,5)  		# [1,100)内5个随机整数
np.random.randint(1,100,(2,3))  	# 2x3 数组

np.random.randn(10,20) 		# 10x20的标准正太 N(0,1)数组
# 符合正太分布N(1, 4) 的 3x4 数组
x = np.random.normal(loc=1, scale=2, size=(3, 4))
x.std() ,  x.var()  ,   x.mean()   		# 标准差,   方差,   均值

NumPy的常用数据类型
在这里插入图片描述

在创建数组时可以用dtype参数指定数据类型。已有的数组可以用astype()方法转换类型。数组元素的类型一般应相同,列表的元素类型允许不同。

In:b=np.arange(5)  		# 默认 'int32' 类型
In: b.dtype
Out: dtype('int32')
In: b[0] = 2**40			# 将报错,整数超范围

In:b=np.arange(5, dtype='float')  #  指定为 'float'
In: b.dtype
Out: dtype('float64')

In: c=b.astype('int')             	# 转为int,b不变,得到新的c
In: c.dtype
Out: dtype('int32')

In: c.astype('bool')		# 转为bool型,非0对应True
Out: array([False,  True,  True,  True,  True])

存取数组元素

基本索引和切片操作
np数组可按类似列表访问的语法,单个索引或切片访问。

b=np.arange(5,10)    		# array([5,6,7,8,9])
b[1],  b[-1],    b[:2], b[1:3]      	# (6, 9, array([5, 6]), array([6, 7]))
b[[0,1,3]]   			# 花式索引 array([5,6,8]),  这里的索引结果是复制
重要:数组切片和列表切片不同,前者是视图,后者是复制。
b=np.arange(5,10)    	# array([5,6,7,8,9])
c=b[0:3]       		# 产生视图,b,c指向同一内存块
c[0]=100     		# 此修改将同时影响 b 和 c
c  			# array([100,6,7])
b           		# array([100,6,7,8,9])
c = b[0:3].copy()  	# 复制数组,这样 b, c分离,不会再互相影响

二维数组

b=np.arange(12).reshape(3,4)
Out:array([[ 0,  1,  2,  3],
                  [ 4,  5,  6,  7],
                  [ 8,  9, 10, 11]])  
b[1, 2]  		# 6,也可写为  b[1][2] 
b[1, 1:3]    	# array([5,6])
b[1]   		# array([4,5,6,7])
b[:,1]          	# array([1,5,9])
b[1:3, 1:4]   	# array([5,6,7],
                        [9,10,11])
b[ [0,1,2], [3,2,1] ]  # array([3, 6, 9]),  将行/列坐标分别排列,花式索引,花式索引是复制操作

布尔索引
筛选出True值对应位置的数据。

np.random.seed(7)
b = np.random.randint(40, 100, size=10) 	# 生成10个的随机整数
Out: array([87, 44, 65, 94, 43, 59, 63, 79, 68, 97])
c = b < 60            				# 生成一个布尔数组c
Out: array([False, True, False, False, True, True, False, False, False, False])
b[c]          		# 利用布尔索引取数据,得到<60的数据
Out: array([44, 43, 59])

b[(b>=60) & (b<=80)]   	# 显示60~80间的数据, 此处用&, 不能用and
b[(b<60) | (b>90)]        	# 显示<60  或 >90的数据,此处用|, 不能用or
b[~(b<60)]		# ~非, 显示 >=60的数据
b=np.array((60, 70, 75, 90, 68, 89))	# 成绩
c=np.array((1 ,  1 ,  1,    2 ,  2,  2))	# 班级
b[c==1].mean()				#  1班平均成绩
x=np.array((70, 75, 92, 68, 89))	# 评分1
y=np.array((75, 69, 93, 70, 85))	# 评分2
np.where(x>y, x, y)			# 取x/y两两比较的较大值
#where函数是当x>y时取x,不然取y,作用效果和np.maximum(x,y)一样
np.where(x>y, 1, 0)			# x>y则取1, 否则取0  

数组运算

数组和单个数据的运算
数组和单个数据可直接运算,不需要编写循环程序处理。

b=np.arange(5)     	# array([0, 1, 2, 3, 4])
b+2 			# array([2, 3, 4, 5, 6])

数组和数组的运算

  1. 数组形状相同时的运算
    两个数组形状(shape)相同时,各位置上的元素对位运算。
a1=np.arange(5)      	# array([0, 1, 2, 3, 4]) 
a2=np.arange(5,10)	# array([5, 6, 7, 8, 9]) 
a1+a2				# array([5, 7, 9, 11, 13])
  1. 数组形状不同时的广播运算
    当两个数组形状(shape)不同时,如果能按广播规则扩展为同形状的数组,则可以运算,如不符合广播规则就不能运算。
a1=np.arange(4)    	     # 一维 (4,)  array([0, 1, 2, 3]) 
a2=np.arange(12).reshape(3,4)	# 二维(3,4) 
a1+a2				
array([[ 0,  2,  4,  6],
           [ 4,  6,  8, 10],
           [ 8, 10, 12, 14]])
上例中的a1是一维数组(4,),a2是3x4的二维数组,两者的维数不同。
a1的维数较小,NumPy在a1的维数前面加1补齐,可近似认为a1的维数变为(1,4)。
现在a1的第0维是1,a2的第0维是3,NumPy将把a1的第0维扩充为3,
相当于将a1的维数变为(3,4),可认为a1在内存中被调整为如下形状:
array([[0,  1,  2, 3],
           [0,  1,  2, 3],
           [0,  1,  2, 3]]
这样,a1和a2的形状一致,就可以完成 a1+a2的运算。

广播规则

  1. 参加运算的数组都向维数最大的数组看齐,维数较小的数组在前面加1补齐。
  2. 结果数组的形状(shape)取各运算数组的各个轴上的最大值。
  3. 若运算数组的某个轴的长度为1,则该轴可扩充为结果数组的对应轴的长度。若轴的长度不为1,则不能扩充。
  4. 检查扩充后所有运算数组对应的轴的长度。若长度都相同则符合规则可以计算,否则违反规则无法计算。
a1=np.array((1,2,3))         a2=np.array((3,4)).reshape(2,1)
形状为(3,) 和2x1的两个数组可运算,结果数组形状为2x3。
先是(1,3)(2,1),然后变成(2,3)(2,3)

形状为3x1 和1x2的两个数组可运算,结果数组形状为3x2。
形状为2x3 和3x2的两个数组不满足规则,无法计算。2x3和4x3的数组也无法广播计算。
结果数组是(3,3),但是(2,3)(3,2)都无法变成(3,3)

数组排序

数组自带sort()排序方法,按从小到大排列。

np.random.seed(7)
b=np.random.randint(1, 20, size=10)
Out: array([16,  5,  4,  8, 15,  9, 15, 11,  9,  8])

c=b.copy()		# 备份
b.sort()   		# 排序后将改变数组b 
b=c.copy()		# 从备份中恢复b
np.sort(b)  		# np.sort不改变数组本身,返回新的有序数组
x=np.argsort(b)  	# 将返回一个代表原数据顺序的有序下标数组
Out: array([2, 1, 3, 9, 5, 8, 7, 4, 6, 0], dtype=int64)
b[x]  			# array([ 4,  5,  8,  8,  9,  9, 11, 15, 15, 16]),花式索引
数组排序不支持列表的reverse=True参数,要从大到小排如下所示:
b[np.argsort(-b)]   	# 注意 -b
Out: array([16, 15, 15, 11,  9,  9,  8,  8,  5,  4])

多维数组排序

多维数组排序时可指定 axis=0() / 1(),排序时默认按最大轴排序。
np.random.seed(7)
b=np.random.randint(1, 50, size=15).reshape(3, 5)
Out:array([[48,  5, 26,  4, 20],
                 [24, 40, 29, 15, 24],
                 [ 9, 26, 47, 43, 27]])

np.sort(b)   		# 默认按axis=1 ,在水平方向上排序
Out:array([[ 4,  5, 20, 26, 48],
           [15, 24, 24, 29, 40],
           [ 9, 26, 27, 43, 47]])

np.sort(b, axis=0)  	# 在竖直方向上排序
Out:array([[ 9,  5, 26,  4, 20],
           [24, 26, 29, 15, 24],
           [48, 40, 47, 43, 27]])

NumPy函数

numpy提供了很多ufunc通用函数,可一次性对整个数组进行计算,无须编写循环处理。格式:np.函数名(数组)
常用函数
有max()、min()、ptp()、sum()、var()、std()等

np.random.seed(7)
b = np.random.randint(1, 20, size=8) # array([16,  5,  4,  8, 15,  9, 15, 11])
np.max(b), np.min(b) ,np.mean(b)     # 最大值、最小值、平均值
np.ptp(b)			# ptp返回数据极差12,即最大值-最小值
np.quantile(b,[0.25,0.5,0.75])	
# 返回分位点对应的分位数,array([ 7.25, 10.  , 15.  ]),
#这个的意思是占了这个数组的0.25的前面数字是比7.25小的数字,
#占了0.5的是数组比10小的数字

一些函数也可写为"数组.函数名()"的形式
b.max(),   b.min(),  b.ptp(),  b.sum(),  b.mean()
b.var(),  b.std() , np.median(b)  # 方差、标准差、中位数
b.argmax(),  b.argmin() 	# 最大值、最小值所对应的索引下标

二维数组
对于二维数组,函数计算时还可指定计算的轴axis=0/1。

b = np.arange(10).reshape(2, 5)
Out[7]: 
array([[0, 1, 2, 3, 4],
       [5, 6, 7, 8, 9]])
np.sum(b)        		# 未指定轴,计算所有数据的和
Out: 45
np.sum(b, axis=0)        	# 指定轴axis=0,行, 沿竖直方向求和
Out: array([ 5,  7,  9, 11, 13])
np.sum(b, axis=1)        	# 指定轴axis=1,列, 沿水平方向求和
Out: array([10, 35])

缺失值

nan表示缺失值,如数组中含有nan ,则函数运算结果为nan。
b = np.array([1, 2, np.nan, np.nan, 3]) 	# 构造含有nan值的数组
np.sum(b)    		# 含有nan值的数组,运算后返回nan
np.isnan(b)        	# isnan()测试是否nan值
Out: array([False, False,  True,  True, False])
np.isnan(b).sum()    	 # 计算nan值个数,True被视为1 ,  结果 2
b[~np.isnan(b)]	# 取出非nan的值
np.nan == np.nan	# nan值很特殊,结果为False
c = np.arange(1, 6) 	# array([1,2,3,4,5])
np.prod(c)		# 累乘  120
np.cumprod(c)  	# 累乘并给出中间结果  array([1,2,6,24,120])
np.cumsum(c)     	# 累加并给出中间结果
Out: array([1,3,6,10,15], dtype=int32)
b=np.array([1,3,3,5,5,7,8])
np.unique(b)   		# 返回不重复的元素值 array([1, 3, 5, 7, 8])
np.all(b)           		# b所有元素都为非0值则返回True
np.any(b)         		# b有任意元素为非0值则返回True
NumPy还提供实现矩阵乘法运算的dot()函数。
a=np.arange(6).reshape(2, 3)
b=np.arange(6, 12).reshape(3, 2)
np.dot(a, b)  #  2x3和3x2数组相乘,结果为2x2数组。写为 a @ b 亦可
Out: 
array([[ 28,  31],
       [100, 112]])

随机函数

np.random 随机数模块
在这里插入图片描述

np.random.seed(7)  		# 设置随机数种子
np.random.rand(2,3)  		# 2x3小数数组
b=np.random.randint(1,100, 20)  # 返回 [1,100)内20个随机整数
np.random.choice(b, 5)	# 从b中随机抽5个数据
card=np.arange(1, 55) 		# 一副牌
np.random.shuffle(card)  	# 乱序 (随机洗牌)
np.argwhere(card==54)	# 查找数据54的位置,array([[2]]

x = ['A',  'B',  'C']
np.random.permutation(x)	# 返回一个排列
Out: array(['C', 'A', 'B'], dtype='<U1')
< : 小端对齐(intelCPU),   U :Unicode编码          1:1个字符长

# 补充  Python中的排列和组合
import  itertools
list(itertools.permutations(x)) 	     # 返回所有可能的排列
list(itertools.combinations(x, 2)) # x中选2个,返回所有可能组合
  • 0
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

ReflectMirroring

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值