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
posted @ 2024-01-26 17:10  辰令  阅读(60)  评论(0编辑  收藏  举报