Python_numpy-增加以及修改维度
从维度上理解
关键点 shape ndim axis size dtype
内存布局: .flags strides nbytes itemsize
切片slice-视图view-副本copy
### ones zeros eye() empty() identify()
## array_like empty_like ones_like zeros_like full_like
## array_split split hsplit vsplit dsplit
# #stack
###多维数组转为一维数组
整体思路
ndim 不同
ndim相同,shape不同--axis-对应维度值为1的,值不为1的
ndim相同,shape相同--根据计算规则rules
广播
ndim不同
在前面补1,继续补1
ndim相同
shape 对应维度元素为1的, 对应维度都没有为1的,需相等
中间过程:
repeat了
最终结果
ndim相同,且取shape对应维度元素最大的元素
###重复-广播
np.tile() 函数用于对数组进行重复reps次。np.tile()是以axis为最小单位(axis-wise)进行重复的
np.repeat() 函数用于对数组元素进行重复。 np.repeat()是以element为最小单位(element-wise)进行重复的
axis:指定沿着哪个轴进行repeat。不指定axis的情况下,会将输入的a数组进行flatten,然后在flatten后的数组上进行repeat
np.broadcast_to()函数用于将数组广播到新形状
reps:对应的英文单词为repeats,是个list,reps表示对A的各个axis进行重复的次数
多维数组维度处理
增加维度
numpy.newaxis对象本身引用的是None,紧增加维度
使用numpy.reshape 或 numpy.expand_dims或 numpy.newaxis
移除维度
axis一维的长度为1,可以将该维去掉,去掉的方法
使用numpy.reshape 或numpy.squeeze
将多维数组压缩为一维数组
使用flatten 或 ravel 以及reshape方法
shape为(batches, d1, d2, d3,...)的多维数组转化为shape为(batches, d1*d2*d3...)的数组,
使用reshape进行转化
###变换维度顺序-axis编号
transpose(指定顺序排列所有的轴编号)
swapaxes(相交换的两个轴编号)
###split
Split an array into multiple sub-arrays.
split函数外,还有array_split函数,
hsplit函数(用于水平分割),vsplit函数(用于垂直分割) dsplit()等等。spli函数只能用于均等分割
def split(ary, indices_or_sections, axis=0):
axis的类型为int,表示的是沿哪个维度切
indices_or_sections的值
如果是一个整数的话,就用这个数平均分割原数组。--数组平均分割的段数
如果是一个数组的话,就以数组中的数字为索引切开
array_split函数用于将数组按指定的位置或段数进行不等分割。
维度计算
(1,8,3)*(n,1,3) -->(n,8,3)
(n,8,3) @ (n,3,3) --> (n,8,3)
矩阵乘积。一个m×n的矩阵就是m×n个数排成m行n列的一个数阵
示例代码
#二维填充
import numpy as np
## ##(N, 8, 3) 变为齐次矩阵 # (N, 8, 4) 第0轴,第1轴,第2轴
a = np.array([[[1,2,3],[3,4,5],[1,2,3],[3,4,5],[1,2,3],[3,4,5],[1,2,3],[3,4,5]],
[[1,2,3],[3,4,5],[1,2,3],[3,4,5],[1,2,3],[3,4,5],[1,2,3],[3,4,5]],])
b = np.pad(a, ((0,0),(0,0),(0,1)), 'constant', constant_values=1.0)
c = np.concatenate([a, np.ones(([a.shape[0],a.shape[1], 1]))], axis = 2)
d = np.dstack([a, np.ones(([a.shape[0],a.shape[1], 1]))])
print(a.shape,a.ndim)
print(b.shape,b.ndim)
print(c.shape,c)
#高维度拼接可以用 concatenate 或者配合 reshape来用三维内
# # c column hstack horizontally
# # r row vstack
# # d depth dstack
#### (N, 8, 4) @ (4,4) --> (N, 8, 4)
## (1, 8, 3) * (n, 1, 3) -> (n, 8, 3)
## (n, 8, 3) @ (n, 3, 3) -> (n, 8, 3)
# 转到齐次矩阵 ##(N, 3) 变为齐次矩阵 # (N, 4)
pts = np.array([[1,2,3],[3,4,5],[1,2,3],[3,4,5],[1,2,3]])
print(pts.shape, pts.ndim)
#pts_homo = np.hstack([pts[:, :3], np.ones((pts.shape[0], 1), dtype=np.float32)])
# except in the dimension corresponding to `axis`,The arrays other axis must have the same shape
pts_homo = np.concatenate([pts[:, :3], np.ones((pts.shape[0], 1))], axis = 1)
print(pts_homo.shape, pts_homo.ndim)
print(pts_homo)
# 第0轴,第1轴, (before,after)的填充值
b_pts = np.pad(pts, ((0,0),(0,1)), 'constant', constant_values=1.0)
print(b_pts)
#pad_width——表示每个轴(axis)边缘需要填充的数值数目。
#参数输入方式为:((before_1, after_1), … (before_N, after_N)),其中(before_1, after_1)表示第1轴两边缘分别填充before_1个和after_1个数
# complex_pts = np.zeros(( pts.shape[0],4))
# complex_pts[:,:3] = pts[:,:3]
# complex_pts[:,3] = np.ones((pts.shape[0]))
# Matrix = np.eye(4,dtype=np.float32)
# Matrix[:3,:3] = rotation_matrix
# Matrix[0:3:,3]= trans
numpy 构成
生成--操作--计算
numpy
##数据相关
关键点 shape ndim axis size dtype
内存布局: .flags strides nbytes itemsize
pytorch --tensor--Attributes of a Tensor
tensor的8个属性:
# 数据相关
t.data # tensor的数据
t.dtype # tensor的数据类型
t.shape # tensor的形状
t.device # tensor所在的设备
# 梯度相关
t.grad # data的梯度
t.grad_fn # 创建tensor的function
t.requires_grad # 是否需要求导
t.is_leaf # 是否是叶子结点
在PyTorch中,只有具有浮点数类型(如float32、float64等)的张量才能够进行自动微分(Autograd)
内存布局:layout torch.layout 是表现 torch.Tensor 内存分布的类,目前只支持 torch.strided
源码:
PyTorch定义了Allocator结构体作为接口,它是内存分配的关键组件之一,允许用户自定义Tensor在CPU、GPU或者其它设备上的内存分配策
Storage和StorageImpl是Tensor的内部类,它们的主要作用是管理数据和管理存储
###运算-
算术运算-逻辑运算-代数运算-矩阵运算-统计运算
arithmetic, linear algebra, matrix manipulation
open3d
class open3d.core.Tensor
shape
[open3d.core.Dtype],
算法
box = box * torch.Tensor([W, H, W, H])
### 中心宽高(xywh)格式的坐标数据,所以把它转换成xyxy格式(左上角点和右下角点)的坐标数据
# from xywh to xyxy
box[:2] -= box[2:] / 2
box[2:] += box[:2]
(0,0)
|------ x->
|
|
|
y
cv2.rectangle() 函数来给图像进行框选 这个函数中的pt1和pt2参数指的就是要框选的图像的左上角点和右下角点
def xywh2xyxy(x):
# Convert nx4 boxes from [x, y, w, h] to [x1, y1, x2, y2] where xy1=top-left, xy2=bottom-right
y = x.clone() if isinstance(x, torch.Tensor) else np.copy(x)
y[:, 0] = x[:, 0] - x[:, 2] / 2 # top left x
y[:, 1] = x[:, 1] - x[:, 3] / 2 # top left y
y[:, 2] = x[:, 0] + x[:, 2] / 2 # bottom right x
y[:, 3] = x[:, 1] + x[:, 3] / 2 # bottom right y
return y
# from xywh to xyxy
box[:2] -= box[2:] / 2
box[2:] += box[:2]
Intersection over Minimum (IoM ) is better suited than Intersection over Union (IoU )
IoU(Intersection over Union,交并比)和
IoM(Intersection over Minimum,交最小比)
IoM是交集面积除以目标边界框和真实边界框中面积较小的那个
命令功能
np.multiply(a,b)
维度一致 :a和b矩阵或数组对应位置相乘
实现对应元素相乘,有2种方式,一个是np.multiply(),另外一个是*
向量元素对应位置相乘:np.multiply(a,b)等价于a*b
向量的内积,即点乘:np.dot(a,b)等价于a@b
向量的外积,即叉乘:np.cross(a,b)
矩阵点乘,即对应元素相乘:np.multiply(a,b)等价于a*b 矩阵点乘要求两矩阵为同型矩阵,即两个矩阵的行数与列数都相同
矩阵叉乘,即矩阵乘法规则运算:np.dot(a,b)等价于a@b 矩阵叉乘中, 前者的列数必须和后者的行数相等
einsum 专门用于张量的计算,比如对数组进行乘法、取和、矩阵乘法、计算内积和外积等。
和其他张量工具相比,einsum的优势在于支持对不同字母进行灵活的指定和重组,同时还可以在计算之前对数组进行各种操作,以适应各种计算需求。
import numpy as np
out = np.clip(a, a_min, a_max, out=None)
inter = np.clip(xy_max-xy_min, a_min=0, a_max=np.inf)
Numpy 的 prod(~) 计算输入数组中值的乘积
numpy是没有属性clamp的。能替代pytorch的clamp的 == numpy的clip
torch.clamp()
这个函数其实就是对张量进行上下限的限制,超过了指定的上限或是下限之后,该值赋值为确定的界限的值
torch.prod()函数对这个张量进行操作,计算所有元素的乘积
dot可以用于numpy中的多维矩阵间的矩阵相乘,torch中的多维使用mm
维度修改函数
numpy
中增加维度用np.expand_dims(x, axis)函数
numpy中的squeeze 函数 从数组的形状中删除单维度条目,即把shape中为1的维度去掉,相当于减少维度
arr_1 = numpy.squeeze(arr, axis = None)
arr表示输入的数组;
axis的取值可为None或0,默认为None,表示删除所有shape为1的维度。axis为0表示删除 一层 shape为1的维度
unsqueeze或view:为数据某一维的形状补1
expand或expand_as:重复数组,实现当输入的数组的某个维度的长度为1时,计算时沿此维度复制扩充成一样的形状
注:repeat与expand功能相似,
但是repeat会把相同数据复制多份,而expand不会占用额外空间,只会在需要的时候才扩充,可以极大地节省内存
np.broadcast_to函数将数组广播到新形状。
numpy.broadcast_to(array, shape, subok=False)[source]
torch:
开辟或删除维度
tensor.unsqueeze(dim=)从第dim维上开拓一个新的维度
tensor.squeeze()将所有长度为1的维度删除
torch.prod(input, dim, keepdim=False, *, dtype=None) → Tensor
将 dim 压缩(请参见 torch.squeeze() ),从而使输出张量减少1个维度。
input(Tensor)–输入张量。
dim(int)–缩小的尺寸。
keepdim(bool)–输出张量是否保持 dim
将两个不同形状的tensor广播成相同形状 torch.broadcast_tensor(a,b)
# [N,2] -> [N,1,2] -> [N,M,2] # [M,2] -> [1,M,2] -> [N,M,2]
A = boxes0.shape[0]
B = boxes1.shape[0]
xy_max = np.minimum(boxes0[:, np.newaxis, 2:].repeat(B, axis=1), np.broadcast_to(boxes1[:, 2:], (A, B, 2)))
numpy.repeat(a, repeats, axis=None);
np.newaxis的作用是:在当前位置,插入一个新维度。np.newaxis 在使用和功能上等价于 None,其实就是 None 的一个别名
Pillow库
Pillow库最常用的两个模块是Image和ImageDraw
PIL.ImageDraw.Draw.rectangle(xy, fill=None, outline=None)
plt.scatter(x, y, s=area, c=colors, alpha=0.5, marker=",")
alpha=0.5 表示不透明度为 0.5
s=size :设置气泡的大小,也就是将"sepal length (cm)"列的数值大小,当作气泡的面积大小,或者说半径大小
其中:x,y,s,c维度一样就能成
参考
numpy和torch函数使用 https://blog.csdn.net/yangjinyi1314/article/details/127119717
https://github.com/pytorch/vision/blob/main/torchvision/ops/boxes.py