矩阵numpy
矩阵利用`numpy`模块进行构建。<br /> `import numpy as np`
创建多维数组
np.array()
`arr = np.array(list, dtype=int)`<br /> 其中,dtype会根据初始化的数据自动进行选择,不为必选参数。
np.asarray()
`arr = np.asarray(list, dtype=int)`<br /> 基本用法和np.array()一样。
生成特定值的矩阵
np.ones(shape=(4,4),dtype=int)
当然像shape=, dtype=这样的句子通常会被省略。np.zeros(shape=5,dtype=int)
np.full(shape=(2,5),dtype=int,fill_value=520)
创建等步长数组
np.arange(0, 10, 0.5)
参数分别是:起始、结束、步长(可以为浮点数,range不能为浮点数),不含终止值;
np.linspace(0, 10, 11)
创建随机数组
np.random.randint(low,high,size)
生成随机数组的范围在[low,high]范围,size是数组的大小,可以是数,也可以是元组(高维),生成数组元
素类型为int型。np.random.random(size)
用于均匀的生成在0-1范围的浮点数。
np.random.normal(loc,scale,size)
用于生成正态分布的随机数,loc表示均值,scale表示方差。
随机种子的生成
计算机中的随机数字都是伪随机,利用算法生成的,如果想要得到相同的随机数字用于实验时复现算法,可以
认为设置随机种子。np.random.seed(seed)
seed是一个整数。
比如:我首先种下一个种子,然后创建随机数组;在之后我种下同样的种子,然后创建同样大小的随机数组将
会得到相同的随机数组。array的基本属性
数组的维度
数组的形状
数组的数据类型
数组元素个数
访问方法(切片索引)
和列表基本相同,也可以进行切片方式访问。切片方式访问返回的是原数组的一个引用,改变切片也会改变原数组(list不会出现这样的情况,返回的切片是一个copy)。所以如果要获得数组的一个copy需要利用copy函数:`arr1 = arr[:2,:2].copy()`
注意事项:
假设数组元素为 T = [[1,2,3],[4,5,6],[7,8,9]](不是list)
利用T[:2,:2]访问和T[:2][:2]访问意思不同。第一种是得到前两行两列的元素;第二种是先得到前两行产生一个新的数组,然后再获取新数组的前两行。其中list构造的多维数组(非严格意义)只能用第二种取元素,不能用第一种,因为list不是严格的多维数组,可以理解为不停一维list的嵌套访问。
值得注意的是:
比如一个numpy a的shape为:(30,3,224,224)则:a[:, 1, :, :]的shape为(30,224,224)也即是会降一个维度(被抽取了一个维度,squeeze(dim=xxx))。
矩阵操作
改变数组形状
利用reshape函数。
arr2 = arr.reshape(shape)
(shape可以是元组:和之前的对应起来,也可以不要括号)
自动计算维度机制:
arr2 = arr.reshape(5,-1)
-1表示此维度自动计算得出。(但是必须整除,不然报错)
数组的合并和分割
合并操作(维度并没有增加)
np.concatenate([arr1,arr2,…,arrn], axis = number)
注:此方法只能够支持具有相同ndim的数组进行合并;(比如二维数组只能和二维数组进行此操作)axis参数之前讲过:从外面向内数axis从0递增。(默认会选择axis=0)默认和axis=0等效!(还是最强的一个拼接方法)
np.vstack([arr1,arr2,arr3,…arrn])
可以支持不同维度的合并操作(智能,但是只能用于二维数组和一维向量,更高为则ndim必须相同),相当于concatenate的axis=0;顾名思意,和布局中的垂直布局类似。
np.hstack([arr1,arr2,arr3,…arrn])
和np.vstack()类似,相当于axis=1,相当于是水平布局。
分割操作
arr1, arr2, arr3 … arrn = np.split(arr, [num1, num2, num3,…numn], axis=number)
其中[num1,num2,…numn]中的numi表示的隔断点的位置(类似于下标索引),axis表示的是按照哪个轴来进行隔断。
# eg
arr1,arr2,arr3 = np.split(arr, [3,6])
关于axis=0时在3、6位置除进行隔断。
up, down = np.vsplit(arr, [``断点数组])
。仍旧相当于axis=0left, right = np.hsplit(arr, [``断点数组])
。仍旧相当于axis=1
值得一提的是:torch.stack([torch1,torch2])
,进行堆叠之后维度会增加,比如两个二维堆叠就会形成一个三维数组。当然可以用dim参数(dim=0,1…),dim和numpy的axis一样。矩阵运算
对于list,内部元素如果想要变为两倍,不能用:`2*list`(只是复制,连接操作);需要利用列表生成式,或者遍历list。<br /> 但是numpy却能够实现这样的操作:(引入的`Universal Function`机制)
例子 | 解释 |
---|---|
2 * arr |
arr里面元素所有翻倍 |
10 - arr |
生成一个和arr一样大小,元素变为10 - arr[index] |
10 / arr |
元素变为10除以arr里面每个元素 |
np.sin(x) |
元素变为每个元素的sin值 |
np.power(3, x) |
元素变为每个3^每个元素值 |
np.power(x, 3) |
… |
np.log(x) |
… |
np.log2(x) |
… |
… | … |
arr1 * arr2 |
两个arr必须一样大,对应元素相乘(统一:此类操作都是对于元素而言) |
arr1.dot(arr2) |
矩阵乘法 |
arr.T |
矩阵转置 |
arr1Inv = np.linalg.inv(arr1) |
矩阵求逆(首先必须可逆,不然会报错) |
arr + vector |
arr为二维,表示每行元素都加上vector值(arr.shape[1] == vector.shape[0]) |
arr.dot(vector) |
矩阵乘法一样的(arr.shape[1] == vector.shape[0])根据vector和arr的位置不同,numpy是智能选择计算方法(和数学里面的一样!) |
np.tile(arr, reps=(r, c) |
arr为向量或者二维数组,reps中的r表示行堆叠几次,c表示列堆叠几次;最终生成二维数组。 |
numpy聚合运算
默认是对所有元素操作(和之前默认和axis=0等效不同)
np.sum(arr, axis=number) or arr.sum(axis=number) |
沿着aixs轴进行求和(聚合),最终会降一个维度 |
---|---|
np.min(arr, axis) arr.min(axis) |
沿着axis求元素最小值;最终降一个维度 |
np.max(arr, axis=number) arr.max(axis) |
沿着指定轴求元素最大值,降一个维度(沿着哪个轴,去掉哪个轴的括号) |
np.prod(arr,axis) arr.prod(axis) |
矩阵指定轴里面的元素全部相乘 |
np.mean(arr, axis) arr.mean(axis) |
指定轴内部的元素进行求平均 |
np.median(arr,axis) arr.median(axis) |
求中位数 |
np.var(arr,axis) arr.var(axis) |
求方差 |
np.std(arr,axis) arr.std(axis) |
求标准差 |
12、numpy arg索引
默认axis不再为0,是对所有元素操作
arr.argmin(axis) or np.argmin(arr,axis) |
沿着指定轴获取最小值的索引,可能生成数组也可能生成数值(看aixs选择一家arr具体维度) |
---|---|
arr.argmax(axis) | 获取最大值索引(自己思考怎样操作最为合理,就明白axis的效果了)。机器学习里面常用 |
arr.sort(axis) | 指定axis进行排序。比如对于二维数组,选择axis=0,效果将是:二维数组里面的那些向量进行排序(向量内部本身不会被排序)à 有一种向量排序方式(标准是模长?貌似是的) |
13、index索引
arr[list] | 按list访问arr,最终生成的形状和list一样 |
---|---|
arr[list1, list2] | (arr为二元:例子)list1和list2构成对(row,col)进行定位 |
arr[:, number] | 第一个维度全选,后一个维度固定 |
arr>3 | 输出一个和arr一样形状的bool数组,每个元素进行判断生成bool值 |
arr[arr>3] | 按bool数组进行元素访问(获取所有大于3的元素) |
np.any(arr>3) | 如果arr中有大于3的元素则为true;如果添加了axis则是对指定axis进行求,可能会生成数组,最终是降一个维度。 |
np.all(arr>3) | 如果arr中全大于3则为true(arr>3是一个bool数组)(默认是对所有元素操作,和axis=0不同) |
assert语句的用法:
assert arr1.ndim==2 and arr2.ndim==2, "输入数据不是矩阵"
如果assert后面的表达式是true则程序继续进行,否则抛出异常,后面的提示信息也会被附带抛出。
14、矩阵其它操作(以二维为例)
from numpy import *
# 增加一行
m_r = append(m, [[1,2,3]], axis=0)
# 注:m是原矩阵,[[1,2,3]]是想要添加的一行(维度相同),aixs=0,相当于之前的vstack(智能)
# 增加一列
m_r = insert(m, [[1],[2],[3]], axis=1)
# 相当于hstack()
# 删除一行
m_r = delete(m, [1], axis=0)
# 注:其中的[1]表示的是行标(第一行);
# 删除一列
m_r = delete(m, s_[1], aixs=1)
# 注:其中的s_[1]表示的是列标(第一列)
# 更新一行
m[1] = [1,2,3]
newaxis增加维度
>>> a
array([[2, 3, 4],
[5, 6, 7]])
>>> a[np.newaxis,:]
array([[[2, 3, 4],
[5, 6, 7]]])
>>> a[np.newaxis]
array([[[2, 3, 4],
[5, 6, 7]]])
>>> a[:, np.newaxis]
array([[[2, 3, 4]],
[[5, 6, 7]]])
>>> a[:, :, np.newaxis]
array([[[2],
[3],
[4]],
[[5],
[6],
[7]]])