python中数据维度的含义_python中那些对数组维度处理的奇技淫巧

python作为数据科学中最受欢迎的编程语言,它的优势就在于对数据的转换,还可以灵活的处理多维数据。下面我们就来看看各种包里边的那些对数据维度操作的函数。

不放官网解释,以通俗语言来解释,先写再整理。要是各位看官想具体了解每个方法,可以逐个百度。

1.numpy

reshape和resize

reshape和resize是numpy里最重要也是最常用的数组,区别就是resize是改变原来数组的维度,而reshape不改变。

import numpy as np

a = np.arange(15).reshape(3,5)

a.reshape(-1,3)

#输出

array([[ 0, 1, 2],

[ 3, 4, 5],

[ 6, 7, 8],

[ 9, 10, 11],

[12, 13, 14]])

a.resize(5,3)

#没有输出,直接改变a

注意resize不接受负数作为参数传递

广播机制

广播机制使维度不同的数组可以操作,这个是numpy中比较重要的特性,稍微不注意也可能出错,因此应该十分注意。

广播机制发生在两种情况下:一种是两个数组的维数不相等,但是它们的后缘维度的轴长相符,另外一种是有一方的长度为1。

举例子说明:

#第一种情况

import numpy as np

arr1 = np.array([[0, 0, 0],[1, 1, 1],[2, 2, 2], [3, 3, 3]])

arr2 = np.array([1, 2, 3])

arr1+arr2

#输出:

array([[1, 2, 3],

[2, 3, 4],

[3, 4, 5],

[4, 5, 6]])

#解释:arr1二维(4,3),arr2一维(3,)后缘维度相同,即倒数第一个维度相同都为3可以自动扩充,进行相加。

#第二种情况

arr1 = np.array([[0, 0, 0],[1, 1, 1],[2, 2, 2], [3, 3, 3]]) #arr1.shape = (4,3)

arr2 = np.array([[1],[2],[3],[4]])

arr1+arr2

#输出:

array([[1, 1, 1],

[3, 3, 3],

[5, 5, 5],

[7, 7, 7]])

#解释:arr1二维(4,3)arr2二维(4,1),满足维度相同,且有一个数组维度为1的条件,自动将arr2扩充为二维。

expand_dims

这个方法的作用是按某一维度进行扩充,本质是增加数组的维度,通常用于计算时候的维度对其,在深度学习这种维度比较多的时候比较常用。

arr = np.array([[1,2,3],[3,4,5]])

arr_new = np.expand_dims(arr, axis=2)

arr_new.shape

#输出:

(2, 3, 1)

#解释,原来的(2,3)维度不变,变成(2,3,1)的维度形式,数组本身发生了改变

tile

上边那个方法呢只能增加一个维度,但是你要想复制原本数组中的数据怎么办呢,这时候需要np.tile()函数,可以指定沿着x/y轴复制数据,默认是沿着x轴。

import numpy as np

a = np.arange(9).reshape(3,3)

np.tile(a,2)

#输出:

array([[0, 1, 2, 0, 1, 2],

[3, 4, 5, 3, 4, 5],

[6, 7, 8, 6, 7, 8]])

np.tile(a,(2,2))

#输出:

array([[0, 1, 2, 0, 1, 2],

[3, 4, 5, 3, 4, 5],

[6, 7, 8, 6, 7, 8],

[0, 1, 2, 0, 1, 2],

[3, 4, 5, 3, 4, 5],

[6, 7, 8, 6, 7, 8]])

flattern和ravel

这两个方法作用就是将数组拉平,简单的说就是多维数组统统转化为1维的。flattern和ravel二者的功能都是一致的,区别在于flatten可以重新分配一个内存空间,ravel不够,也就是说ravel以后的新数组由于是原数组的展示方式,所以你更改他的值原数组的值也会跟着变,因此使用中一般使用flattern即可。

a=np.arange(12).reshape(3,4)

a.flatten()

a.ravel()

输出:

array([ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11])

transpose和T

这两个函数就是二维数组转置用的,没啥好解释的,就是行列互换,array/matrix包括pandas的dataframe都可以用这个函数。此处不举例子。

tranpose

当超过三维的时候,transpose就是交换数组的维度。

transpose如果不加参数,就是倒叙转换,如(2,1,1)倒序就变为(1,1,2)。

当然你可以自己指定参数,用个括号括起来,如(1,0,2)。举例子来理解:

a = np.arange(12).reshape(2,2,3)

输出:

array([[[ 0, 1, 2],

[ 3, 4, 5]],

[[ 6, 7, 8],

[ 9, 10, 11]]])

a.transpose((2,1,0))

输出:

array([[[ 0, 6],

[ 3, 9]],

[[ 1, 7],

[ 4, 10]],

[[ 2, 8],

[ 5, 11]]])

解释:

因为维度要对齐,其实就是现有维度的两两组合。

squeeze

这个方法是减少数组的维度,减少的那个维度是1维的,有没有都一样,所以可以去掉。

a = np.arange(10).reshape(1,1,10)

print(a.shape)

输出:(1, 1, 10)

print(a.squeeze().shape)

输出:(10,)

meshgrid

这个方法比较高级,一般用在画图里边。给你两个数组,然后生成一个网格点的坐标体系,这个笔者就在matplotlib的气泡图里用过,简直不要太方便。

x = np.array([[0, 1, 2, 3],

[0, 1, 2, 3],

[0, 1, 2, 3],

[0, 1, 2, 3]])

y = np.array([[0, 0, 0, 0],

[1, 1, 1, 1],

[2, 2, 2, 2],

[3, 3, 3, 3]])

X,Y = np.meshgrid(x,y)

print(X)

print(Y)

#输出太长了,自己打出来看吧

有了numpy的维度处理基础知识,其他任何框架的维度转换基本就是这些方法的转换,有时候会有一些新方法出现,但大抵的思路都是差不多的。

2.pytorch

pytorch的维度变化和numpy有区别,需要注意一下。

view

view相当于reshape,用法和reshape完全一样

import torch as t

t1 = t.Tensor([[1,2],[3,4]])

t1.view(4,)

输出:

tensor([1., 2., 3., 4.])

gather

这个函数作用就是根据索引提取数据,什么作用呢,多分类问题中可以把maxindex传进去提取正确的结果。

使用方法:torch.gather(input, dim, index, out=None)

input就是你输入的数组,dim是要在哪一维度上操作,index是要取数据的下标,跟dim取值有关,如果是1就按列取数,如果是0就按行取数。

import torch as t

t1 = t.Tensor([[1,2],[3,4]])

print(t1)

t.gather(t1, dim=0, index=t.LongTensor([[0,1],[0,1]]))

#输出

tensor([[1., 4.],

[1., 4.]])

#解释

#dim=0横向,比如第一个[0,1]中的就是第2行第2列

注意:index需要是pytorch中的LongTensor数据类型,Tensor都不可以。

squeeze和unsqueeze

这两个方法和numpy中的一样,squeeze就是压缩第n维为1的数。注意只有在使用squeeze时,只有维度为1才会被压缩,否则不起作用,但是你如果不加参数,所有维度为1的维度都会被压缩。

import torch

a = torch.Tensor([[[1, 2, 3], [4, 5, 6]]])

b = a.view(-1,3,2)

print(b.size())

#输出:torch.Size([1, 3, 2])

b1 = b.squeeze(1)

print(b1.size())

#输出:torch.Size([1, 3, 2])

b2 = b.squeeze(0)

print(b2.size())

#输出:torch.Size([3, 2])

b3 = b.squeeze()

print(b3.size())

#输出:torch.Size([3, 2])

unsqueeze就是在指定维度增加一个维度1。

b.unsqueeze(2).size()

#输出:torch.Size([1, 3, 1, 2])

transpose和permute

这两个方法都是维度转换用的,本质是一样的,就是交换一个tensor的两个或几个指定的维度。但是transpose是通过torch.transpose调用,而permute要通过直接通过permute调用。permute比transpose好在可以同时对多个维度进行交换,具体用哪个看你的习惯吧。

b.size()

#输出:torch.Size([1, 3, 2])

torch.transpose(b,2,1).size()

#输出:torch.Size([1, 2, 3])

b.size()

#输出:torch.Size([1, 3, 2])

b.permute(2, 0, 1).size()

#输出:torch.Size([2, 1, 3])

expand和repeate

这两个函数和numpy的tile差不多吧,都是扩张维度。

首先是expand,他有个特性,只有维度为1的那一维才可以扩张,维度不为1的那一维传参的时候只能写的和原来的维度一样。他返回的是一个视图,不占内存的。

然后是repeate,repeate生成新张量,占内存的。而且这个方法不再指定只有维度为1的可以扩张,所有维度都可以扩张。

x = torch.Tensor([[1], [2], [3]])

x.size()

#输出:torch.Size([3, 1])

x.expand(3,4).size()

#输出:torch.Size([3, 4])

x.repeat(3,4).size()

#输出: torch.Size([9, 4])

转置

转置只适用于二维,直接tensor.t就好了,不举例子了。

pytorch基本就这些了,如果遇到新的,我会再补充。

3.tensorflow

tensorflow的维度变化函数和numpy基本是一样的,reshape,transpose,squeeze函数是经常使用的方法,只不过前缀变为tf,处理的数据类型也变为张量了。

shape和ndim

返回张量的维度,这个没有啥好说的,其中shape返回详细的维度,ndim返回张量有几个维度。值得注意的是在tensorflow里shape和ndim是tensor的属性,不是方法,不用加括号。

import tensorflow as tf

tf.__version__

a = tf.convert_to_tensor([[1,1],[1,1]])

a.shape

#输出:TensorShape([2, 2])

a.ndim

#输出:2

reshape

这个是老生常谈的一个方法了,就是改变数组的维度,可以自动计算支持-1作为默认维度。

a = tf.random.normal([4, 28, 28, 3])

tf.reshape(a, [4, 28*28, 3]).shape

tf.reshape(a, [4, -1, 3]).shape

#输出都是TensorShape([4, 784, 3])

transpose

眼熟不,这个transpose简直哪个包里都有,tensorflow里边有个perm参数,可以随意交换位置,这个和torch的permute差不多。当然了tf2.0里边也有相应的permute函数,tf.keras.backend.permute_dimensions( x,pattern),pattern和perm一样,我就不举例子了。

a = tf.random.normal([4, 28, 28, 3])

a.shape # TensorShape([4, 28, 28, 3])

tf.transpose(a, perm=[0,3,1,2]).shape

#输出:TensorShape([4, 3, 28, 28])

expand_dims

这个是tensorflow里的扩展维度方法,可以设置沿着指定的轴扩展。

a = tf.ones([4,35,10])

a.shape

# 输出:TensorShape([4, 35, 10])

tf.expand_dims(a, axis=0).shape

#输出:TensorShape([1, 4, 35, 10])

squeeze

squeeze是压缩维度为1的维度,和numpy,pytorch相同的,但是tf里没有unsqueeze这个方法,大家要注意。

tf.expand_dims(a, axis=0).shape

a = tf.ones([1,4,35,10])

tf.squeeze(a).shape

#输出:TensorShape([4, 35, 10])

broadcast_to

这个函数的作用很显然了,就是手动扩展维度,类似于numpy里的广播机制,作用呢就是使两个tensor可以矩阵乘。

a = tf.ones([4,5,6])

b = tf.fill([6,4], 2.)

bb = tf.broadcast_to(b, [4,6,4])

(a@bb).shape

#输出:TensorShape([4, 5, 4])

concat

tensorflow里拼接两个张量的方法,可以设置沿指定轴拼接。

t1 = tf.convert_to_tensor([[1, 2, 3], [4, 5, 6]])

t2 = tf.convert_to_tensor([[7, 8, 9], [10, 11, 12]])

tf.concat([t1, t2], 0) # [[1, 2, 3], [4, 5, 6], [7, 8, 9], [10, 11, 12]]

tf.concat([t1, t2], 1)

#输出:

array([[ 1, 2, 3, 7, 8, 9],

[ 4, 5, 6, 10, 11, 12]], dtype=int32)>

tensorflow里对维度处理的函数比较少,要是想扩展功能咋办,你可以先转化为numpy的array处理完再转换为tensor就好了。

4.keras

Reshape

同reshape,在keras.layers库里,是一个层。

注意啊tensorflow升级为2.0以后,以前的导入方法不管用了,要在前边加一个tensorflow。

from tensorflow.keras.models import Sequential

from tensorflow.keras.layers import Reshape

model = Sequential()

# 改变数据形状为3行4列

# 模型的第1层必须指定输入的维度,注意不需要指定batch的大小

model.add(Reshape((3, 4), input_shape=(12, )))

# 改变数据形状为6行2列

model.add(Reshape((6, 2)))

# 改变数据形状为 第2,3维为(2,2),根据数据元素数量自动确定第1维大小为3

model.add(Reshape((-1, 2, 2)))

# 改变数据形状为 第1,2维为(2,2),根据数据元素数量自动确定第3维大小为3

model.add(Reshape((2, 2, -1)))

model.summary()

#输出:

_________________________________________________________________

Layer (type) Output Shape Param #

=================================================================

reshape (Reshape) (None, 3, 4) 0

_________________________________________________________________

reshape_1 (Reshape) (None, 6, 2) 0

_________________________________________________________________

reshape_2 (Reshape) (None, None, 2, 2) 0

_________________________________________________________________

reshape_3 (Reshape) (None, 2, 2, None) 0

=================================================================

Total params: 0

Trainable params: 0

Non-trainable params: 0

Permute

毫无疑问,Permute在keras里也变成层了,但功能是不变的。

model = Sequential()

modle.add(Permute((2,1),input_shape=(10,64)))

#现在变为(64,10)了

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值