最近再学习python经常会遇到一个参数axis,常常会被不同的取值搞得有点头大,于是查找几个知乎大佬文章,揣摩了揣摩,加上上自己的理解整理一下。
一般来说数据会有1维,2维,3维,4维,,,,等等更多的维度,对于我来说比较长打交道是2维的和3维的甚至会有4维的(少见)。我是做kg的经常会遇到一些时间序列数据(N,T,E)格式的数据。N就是样本批次大小,T就是时间序列长度,E就是词向量。
先说说axis,借用大佬的话就是axis是经常在numpy和tensorflow中用到,是作为对矩阵(张量)进行操作时需要指定的重要参数之一,一般的axis取值会有-1,0,1,2.,,,在pyhton中,-1代表倒数第一个,也就是说,假如你的矩阵shape=[3,4,5],那么对这个矩阵来说,axis=-1,其实也就等于axis=2。因为这是个三维矩阵,所以axis可能的取值为0,1,2,所以最后一个就是2。你可以自己试试看两个取值结果是否相同。(这个就涉及python的基本知识)
对于矩阵操作中的axis的理解,以及axis=-1的理解
一.二维数据的理解
第一种是表格的时候 套用知乎大佬一张图片清晰易懂简单明了
一般我们再在进行数据预处理的时候可能要对某一行或者某一列数据进行标准化处理,此时就可以根据需要选择axis=0或者1方向
简单的解释就是:
axis=0 代表跨行(我的理解就是列方向) 就是说通俗的理解就是 两个二维的矩阵数据 沿着列的方向进行拼接
例如:
def concat_():
a=[
[1,2,3],
[3,2,1]
]
b=[
[5,6,7],
[8,7,9]
]
with tf.Session() as sess:
print(sess.run(tf.concat([a,b]),0))
print(sess.run(tf.concat([a,b]),1))
分别将a和b沿着axis=0和axis=1两个方向进行拼接 结果如下:
第一个
可以理解为 将a的子元素 与 b的子元素 沿着列的方向进行拼接
[
[1,2,3],
[3,2,1],
[5,6,7],
[8,7,9]
]
第二个
可以理解为将 a 的子元素 与 b 的子元素 沿着行的方向进行拼接
[
[1,2,3,5,6,7],
[3,2,1,8,7,9]
]
二.3维的数组情况下要更为复杂一些:
关于3维度的数据,我把它理解为一个立体几何的形状,反正目前为止我这么理解没出现过什么错误.
我们直接上例子:
设zeros是一个shape=[3,4,5]的矩阵,如下:
这里说一个我自己曾经的误区:因为形状(4,5)就是说的是四行五列的矩阵,一直以来我就把(3,4,5)当作是三行四列至于这个5也是一直没搞清楚,哈哈。。。。后来搞清楚了(3,4,5)说的是四行五列矩阵在空间中被拉伸3,就像在图片数据里的C一样(我类比图像中的C通道概念感觉好理解一些)
下面咱们继续讨论:
zeros=
[[[-0.4546477 0.74564657 -0.56464645 0.24321035 -0.3538919 ]
[-0.45435346 0.1288028 -0.53454543 -0.07217035 0.05287632]
[ 0.15845934 0.07064888 0.00922218 0.2841002 -0.24992025]
[ 0.43347922 -0.43738696 -0.08176881 0.34185413 -0.2826353 ]]
[[-0.08590135 0.06792518 -0.07807922 -0.28746927 -0.10613027]
[ 0.07476929 0.132256 -0.0926154 0.39621904 0.2497718 ]
[-0.15389556 0.0867373 0.19403657 -0.11003655 0.317669 ]
[ 0.3949038 -0.17275128 0.34710506 -0.02576578 -0.17427891]]
[[-0.27703786 0.02631402 0.22129896 -0.07714707 0.41439041]
[-0.08512023 0.19059369 -0.13418713 -0.12881753 -0.26143318]
[-0.333749 0.27034065 0.45429572 -0.46164128 -0.3955955 ]
[ 0.24430516 -0.3841647 0.37126407 -0.463441 -0.1441828 ]]]
#使用python进行一些基本操作
x = tf.math.argmax(zeros, axis=-1)
y = tf.math.argmax(zeros, axis=1)
z = tf.math.argmax(zeros, axis=0)
with tf.Session() as sess:
sess.run(tf.global_variables_initializer())
print(zeros.eval())
print(x.eval())
print(y.eval())
print(z.eval())
#运行代码得到的结果 这里返回的是最大数值对应的下表索引
[[1 1 3 0]
[1 3 4 0]
[4 1 2 2]] # axis=-1, shape=[3,4]
[[3 0 2 3 1]
[3 1 3 1 2]
[3 2 2 0 0]] # axis=1, shape=[3,5]
[[1 0 2 0 2]
[1 2 1 1 1]
[0 2 2 0 1]
[0 1 2 0 2]] # axis=0, shape=[4,5]
不知道你们理解不,反正我当时看到这个地方的时候有点蒙圈.大佬们的解释是从矩阵方面入手的.就拿上面的例子来说写成矩阵就是这个样子.
zeros=
= [[[a000,a001,a002,a003,a004],
[a010,a011,a012,a013,a014],
[a020,a021,a022,a023,a024],
[a030,a031,a032,a033,a034]]
[[a100,a101,a102,a103,a104],
[a110,a111,a112,a113,a114],
[a120,a121,a122,a123,a124],
[a130,a131,a132,a133,a134]]
[[a200,a201,a202,a203,a204],
[a210,a211,a212,a213,a214],
[a220,a221,a222,a223,a224],
[a230,a231,a232,a233,a234]]
如此就清晰明了了.
我把上面的数据分为 上(就是a000-a030) 中(a100-a130) 下(a200-a230) 三个块如此就方面交流了.
这个时候就不能用表格思维来想了,应该这么来
用大佬的话就是: 设axis=i,则沿着第i个下标变化的方向进行操作
以axis=0为例:
就是沿着第0个下标(最左边的下标)变化的方向进行操作,当axis=0的时候咱们看每个元素下标的第一个字符(因为在python中我们是从0开始),若是1的话就是第二个.以此类推.
当axis=0的时候我们可以看到上部分的下标都是0中部都是1下部都是2也就是说数据的变化是上中下这么来的,如此可以手动绘制一个长方体立体几何下部的四行三列数据作为底面上部的作为上面,而每一部分的第一行数据所在面面向我们,三层叠加高度为三,面向我们的形状为3x5
所以整个长方体的尺寸就是5x4x3
当axis=0的时候因为是从上中下部分改变的所以从上面俯视面的shape(4x5)
当axis=1的时候因为是在每一部分变动的方向是我们看的方向改变的的所以正视面的shape(3x5)
当axis=-1的时候因为是从每一部分的行方向改变的所以看的是侧视图的shape(3x4)
这种方法有点取巧…
咱们可以交流交流
参考资料:
https://blog.youkuaiyun.com/weixin_37821353/article/details/88367211
https://blog.youkuaiyun.com/fangjian1204/article/details/53055219