Numpy
目录
Numpy简介
Numpy(Numerical Python)是一个开源的Python科学计算库,用于快速处理任意维度的数组
Numpy支持常见数组和矩阵的操作
Numpy使用ndarray对象来处理多维数组,该对象是一个快速而灵活的大数据容器
创建:np.array([])
ndarray与原生Python List运算效率对比
import random
import time
import numpy as np
import matplotlib.pyplot as plt
plt.rcParams['font.sans-serif']=['SimHei'] #用来正常显示中文标签
plt.rcParams['axes.unicode_minus']=False # 正常显示负号
a = [] # 定义空列表a
for i in range(100000000):
a.append(random.random()) # 用随机数填充空列表a
%time sum1 = sum(a) # 列表数据相加
b=np.array(a) # 转换为Numpy的Array格式
%time sum2 = np.sum(b) # Numpy的方法实现数组中元素值相加
Wall time: 429 ms
Wall time: 129 ms
原因:ndarray中所有元素的类型必须相同,而Python列表中的元素类型是任意的
实质:
- (1)ndarray所存储的数据就是值,使用时直接使用(体现出Numpy的内存块风格:一体式存储);而Python List存储的是地址,使用时根据地址寻值
- (2)底层区别:Numpy底层采用C语言编写,内部解除了全局解释锁(GIL),因此对数组的操作不受到Python解释器的限制(因此,效率高于Python原生代码)
ndarray支持并行化运算(向量化运算)
N阶数组 ndarray
属性名字 | 属性解释 |
---|---|
ndarray.shape | 数组维度的元组 |
ndarray.ndim | 数组维数 |
ndarray.size | 数组中元素数量 |
ndarray.itemsize | 一个数组元素的长度(字节) |
ndarray.dtype | 数组元素的类型 |
(1)创建数组
a = np.array([[1,2,3],[4,5,6],[7,8,9]],dtype=np.float32)
print(a)
print(a.dtype)
【注意】在不指定dtype时,默认整数为int64,小数为float64
(2)生成数组
生成纯1数组
ones = np.ones([3,4])
print(ones)
生成纯0数组
zeros = np.zeros_like(ones)
print(zeros)
从现有数组生成
np.array()
np.asarray()
c = np.array([[1,2,3],[4,5,6],[7,8,9]],dtype=np.float32)
# 从现有数组中创建
c1 = np.array(c) # 深拷贝
# 相当于索引的形式,并没有真正创建一个新的数组
c2 = np.asarray(c) # 浅拷贝
print(c1)
print()
print(c2)
生成固定范围数组
np.linspace(statr,stop,num,endpoint)
- start 序列起始值
- end 序列终止值
- num 要生成的等间隔样例数量,默认为50
- endpoint 序列中是否包括stop的值,默认为True
np.linspace(0,50,5,True) # 生成5个范围在0到50的数字,包含50
np.arange(start,end)
- 起始值
- 终止值
- 步长
np.arange(0,10,2)
np.logspace(start,end,num)
- start 起始值
- end 终止值
- num 元素数量
默认生成以10的N次幂的数据
可通过base设置基数
np.logspace(1,10,10,base=10)
生成随机数组
均匀分布
np.random.uniform(low=0.0,high=1.0,size=None)
# lo::采样下界 float类型 默认为0
# high:采样上界 float类型 默认为1,若high为空,取值为0到low
# size:输出样本数目
np.random.uniform(low=10,high=100,size=10)
np.random.uniform(low=10,size=(5,5)) # 但是不能写 high = None
# 画图查看分布情况
x = np.random.uniform(low=0,high=1,size=300) # 大小范围0-1,生成300个元素
plt.figure(figsize=(10,5),dpi=300) # 长10宽5,分辨率300
plt.hist(x,bins=60) # 分成60份(300/60=5) 份数越多,越精准
plt.show()
# print(x)
正态分布
正态分布是一种概率分布,正态分布是连续型随机变量的分布,有两个参数。
第一个参数 μ(wei) 服从正态分布的随机变量的均值
第二个参数 δ(delta) 随机变量的方差
因此正态分布记作N(μ,δ)
- μ 决定位置(极点对应的x轴坐标,当μ=0时对应x轴的0,关注极点在Y轴左右),
- δ
标准差
决定分布的幅度(标准差越大,越分散,图形越是胖矮;标准差越小,越集中,图形高瘦)
当 μ = 0 ,δ = 1 时的正态分布是标准正态分布
创建正态分布,有三种办法
- np.random.randn(d0,d1,…,dn) 功能: 从标准正态分布中返回一个或者多个样本值
- np.random.normal(loc=0.0,scale=1.0,size=None) 备注: loc:float 此概率分布的均值;scale 此概率分布的标准差;size输出的shape,默认为None,只输出一个值
- np.random.standard_normal(size=None) 功能:返回指定形状的标准正态分布数组
a = np.random.normal(0,1,1000)
b = np.random.standard_normal(1000)
plt.figure(figsize=(10,5),dpi=72) # 长10宽5,分辨率72
plt.hist(a,bins=100,alpha=0.5,color="g")
plt.hist(b,bins=100,alpha=0.5,color="r")
plt.show()
(3)数组索引、切片
stock = np.random.normal(0,1,(8,10))
print(stock)
# 获取前两行(0-1),前3列(0-2)的数据
stock[0:2,0:3]
# 前两行是 0,1 因此要写0:2,意思是从索引0开始,到2结束,但不包括2
# 获取第三行第二列的值
stock[2:3,1:2]
# 获取第三行第二列的值
stock[2,1]
(4)形状修改
stock = np.array([[[-1,-2,-3],[1,2,3],[11,12,13]],[[-4,-5,-6],[4,5,6],[14,15,16]],[[-7,-8,-9],[7,8,9],[17,18,19]],[[11,22,33],[44,55,66],[77,88,99]]])
print(stock)
stock.shape # 由此可见目前是四层 每层是三行三列
stock.reshape(3,4,3) # 形状变换为 三层,每层四行三列,
stock.reshape(-1,1,12) # 形状变换为 一行十二列。至于几层写的-1,表示待计算
stock.reshape(-1,1,12).shape # 由此可知自动计算出来的是3层
# 转置 行列互换
stock.reshape(-1,1,12).T
stock.reshape(-1,1,12).T.shape
print(stock)
stock.resize(2,6,3) # 两层,每层六行,每行三列
stock
总结:
- reshape 产生新变量,不更改原值
- resize 在原值基础上修改
(5)类型修改
stock
stock.astype(float)
#np.array(stock).tostring() # 已弃用
np.array(stock).tobytes()
(6)数组去重
arr = np.array([[1,2,3,4,5],[1,2,3,4,5]])
np.unique(arr)
(7)数组运算
数组和数字的运算
arr = np.array([1,2,3,4,5])
print(arr)
arr-1
arr+2
arr/2
arr*2
arr
数组和数组间的计算
前提条件:
- 维度相等
- shape(其中相对应的一个地方为1)
也就是要满足广播机制。广播机制介绍如下:
广播机制
执行broadcast的前提在于两个ndarray执行的是element-wise运算
Broadcast机制的功能是为了方便不同形状的ndarray(Numpy库的核心数据结构)进行数学运算
A (1d array):10
B (1d array):10
如上,A,B都是1维,且相等,因此能运算
A (1d array):10
B (1d array):12
如上,A,B都是1维,但形状不一样,因此不能运算
A (1d array): 2 x 1
B (1d array):8 x 4 x 2
如上,A,B维度不相等,1和2,能运算,但是2和4,不相等,则不能运算,因此AB也不能运算
A (1d array): 3 x 1
B (1d array):8 x 1 x 2
如上,A,B维度不相等,1和2,能运算,3和1,能运算,因此AB能运算。(因为有1)
A (1d array): 3 x 1
B (1d array):8 x 3 x 2
如上,A,B维度不相等,1和2,能运算,3和3,因为相等,所以能运算,因此AB能运算。
arr1 = np.array([[1,2,3,2,1,4],[5,6,1,2,3,1]]) # 2阶1维 两行六列 (1d array) 2 x 6
arr2 = np.array([[1],[2]]) # 2阶1维 两行一列 (1d array) 2 x 1
# 因为2对应的是2,相等;6对应1,因此能进行运算
arr1+arr2
通过上面案例分析可知,arr2的唯一一个元素被广播后,与arr1对应元素进行运算
(8)矩阵运算
矩阵乘法API
arr1 = np.array([[1,2],
[5,6],
[1,5]])
arr2 = np.array([[0.5],[0.1]])
print(arr1,"/n","/n",arr2)
np.matmul(arr1,arr2) # 矩阵相乘
np.dot(arr1,10) # 点乘(特点:dot支持矩阵和数字相乘)
np.dot(arr1,arr2) # 点乘(矩阵和矩阵相乘时和matmul无区别)
原创文章,作者:jamestackk,如若转载,请注明出处:https://blog.ytso.com/tech/python/276934.html