一、什么是numpy
二、为什么要有numpy
python中没有数组,只有list。list相对于数组而言的缺点是,python作为一门动态语言,每一个元素的类型可以是不一样的,那么对于列表中的每一个元素python需要检查他的类型,当数据量较大时,解释速度会比数组更慢。
python的库中是有array的,可以用来生成’数’组。array.array(‘数据类型’, 列表 )。但是它没有将这些数据看作向量或者矩阵,没有为这些数据配备向量相关或矩阵相关的运算,所以在机器学习中使用并不方便。numpy正是因此出现的。
numpy中的元素必须是统一类型,优先级:字符串 >浮点型> 整形
三、numpy怎么用
基础使用
导入numpyimport numpy as np
查看版本print(numpy.__version__)
随便创建一个数组nparr = np.array(i for i in range(10)),nparr = np.array([1,2,3])
查看numpy产生数组的类型print(x.dtype) # datatype的缩写
创建0数组np.zeros(10) np.zeros((3,5)) # 三行5列
创建1数组并指定形状和类型np.ones(shape=(3,5), dtype=int) np.ones([3, 5])
创建单一数值数组np.full(shape=(3, 5), fill_value=6, dtype=int)
使用简单的方式创建数组nparr= np.arange(10,0.2)# 步长可以是浮点数
创建等差数列nparr = np.linspace(20,5) # 从0到20等步长切出五个数字
random
是numpy中就有的random
import numpy
numpy.random.random((1000,20)) # 生成1000行,20列,范围在0-1之间的浮点数
numpy.random.randint(0, 10, 10) # 前面俩是范围,第一个参数可以不写,后面是数量
numpy.random.randint(0, 10, size = 10) # 形参关键字size
numpy.random.randint(0, 10, size = (3, 5)) # 可以传元祖
numpy.random.seed(666) # 随机种子,参数是数字,一样的种子被重复种下会长成一样的树,全局有效,即使用一次后下一次还会生效
numpy.random.normal(0, 1,size=1000)# 生成正态分布数据,均值,方差,矩阵(元组),size= # 均值默认0,方差默认1
基本属性
nparr.nidm 查看几维数组
nparr.shape 返回元组,查看元素数量与维度
nparr.size 返回元素个数
numpy.array的数据访问
nparr[0][0] # 不建议,不可以切片多维数组(第五行),为了养成使用习惯统一使用下面的方式
nparr[(0,0)] # 等同于下面
nparr[0,0]
# numpy可以使用切片
nparr[3:8] #切一维数组3~8
nparr[:2, :3] # 切前2行,前3列
# 注意,numpy切片后修改元素时修改的是原矩阵的数值
subx = nparr[:2, :3].copy() # 这样才能创建一个新的矩阵
np.imread('路径') # 把图片读成数组
reshape
# 改变矩阵形状
new_nparr = nparr.reshape() # 重置的不是原来的矩阵,所以要赋给新的值
nparr.reshape(10, -1) # 把该向量或矩阵变成10行的矩阵,每列而有多少元素不管
nparr.reshape(-1,10) # 把该向量或矩阵变成10列的矩阵,每行而有多少元素不管
合并操作
np.concatenate([x,y], axis=0) # []内可以有好几个矩阵,axis默认为0,合并行,1是合并列,也可以填更高的维度,只能拼接同维矩阵
np.concatenate([x,y]) # 当x是一维,y是二维就不行了,需要转化成同维(reshape)
np.vstack([放入矩阵]) # 可以智能竖直拼接,不用reshape vertical
np.hstack([放入矩阵]) # 可以智能横向拼接,不用reshape Horizontal
分割操作
nparr = np.arange(10)
x1, x2, x3 = np.split(nparr, [3,7]) #
out: x1 = 0,1,2
x2 = 3,4,5,6
x3 = 7,8,9
a = np.arange(16).reshape([4, 4])
a1, a2 = np.split(a, [2]) # 默认横着切,用axis参数可以调节
out: a1 = [[0,1,2,3],
[4,5,6,7]]
a2 = [[8,9,10,11],
[12,13,14,15]]
a = np.vsplit() # 竖切,等价于split中axis等于0
a = np.hsplit() # 横切,等价于split中axis等于1
Universal Functions
numpy类型的矩阵可以对本身与数字进行四则运算nparr + 1
np.sin(nparr)
np.abs(nparr) # 绝对值
np.cos(nparr)
np.tan(nparr)
np.around(3.14) # 四舍五入值
np.ptp(nparr) # 极差
np.exp(nparr) # 每一个元素的e次方
np.power(3, nparr) # 3为底的
np.log10()
矩阵与另一个矩阵之间可以加减,但不能乘除,乘除结果是对应元素之间的乘除,而不是矩阵的乘除
nparr1.dot(nparr2) # 矩阵1和矩阵2相乘,所有横乘竖的第一个相加成为第一个值
nparr.T # 矩阵转置
np.vstack([矩阵] * 2 ) # 整个矩阵复制后竖向拼接
np.tile(nparr, (2,1)) # 堆叠,在行向量堆叠俩次,列向量堆叠一次
矩阵的逆
invA = np.linalg.inv(A)
# 矩阵的逆和原矩阵相乘得出的单位矩阵对角线是都是1
只有正方的矩阵才有逆,我们可以求伪逆矩阵
pinvA = np.linalg.pinv(A)
聚合运算
np.sum(nparr,axis=参数) # 等价于nparr.sum()
np.count_nonzero(nparr)
np.min(nparr) # 等价于nparr.min()
np.max(nparr) # 等价于nparr.max()
np.prod(nparr) # 乘积
np.mean(nparr)
np.median(nparr)
np.percenttile(nparr, q=50) # 求50%的百分位点
np.var(nparr) # 求方差
np.std(nparr) # 标准差
排序和使用索引
np.random.shuffle(nparr) # 打乱
np.sort(nparr) # 排序,并返回一个新值
nparr.sort() # 排序nparr本身
# 当nparr是二维数组时
np.sort(nparr, axis=0) # axis默认是1
np.argsort(nparr) # 返回排序后元素在原数组的索引
np.partition(nparr, 3) # 比3小的放左边,比3大的放右边
np.argpartition(nparr, 3) # 返回数组,比三小的值的原索引在左边,右边相反
fancy indexing和比较运算
nparr = np.arange(16)
ind_1 = [3, 5, 8]
ind_2 = [[0, 2],
[1, 3]
]
print(nparr[idx_1])
print(nparr[idx_2])
=========================
out:
arrray([3, 5, 8)
array([[0, 2],
[1, 3]
])
nparr1 = nparr.reshape(4, -1)
row = np.array([0, 1, 2])
clo = np.array([1, 2, 3])
clo1 = [True, False, True, True]
nparr1[clo, row]
nparr1[0, col]
nparr1[:2, col]
nparr1[1:3, col1]
out:
array([1, 6, 11])
array([1, 2, 3])
array([[1, 2, 3],
[5, 6, 7]])
array([[4, 6, 8],
[8, 10, 11]])
比较:可以指定行或列
nparr > 3 # 返回布尔类型数组
np.sum(nparr > 3)
np.count_nonzero(nparr <= 3)
np.any(nparr >= 0) # 有一个等于零返回True
np.all(nparr > 0) # 全等于0返回True
np.count((nparr > 3) & (nparr < 10))
& | ~ 与或非
x[x[:,3] % 3 == 0, :] # 抽取能整除3的行
p12到p21不知道有没有看过,先掠过了
arg运算
import numpy as np
np.argmin(参数) # 返回最小值的索引
np.argmax(参数) # 返回最大值的索引