numpy操作中的axis的理解

时间:2022-01-28 01:11:16

Numpy操作中的axis

这是我参考的连接numpy模块中的axis理解
最近发现,numpy的很多操作都是和axis联系在一起的,以前只是遇到了稍微记一下,过后又忘了,这次做好笔记,加深理解。

首先为什么会有axis这个概念?

因为在numpy模块中,大多数处理的是矩阵或者多维数组,同时,对多维数组或者矩阵的操作有多种可能,为了帮助实现对数组或矩阵各种各样的功能,就有了axis

下面举个例子,选取不同的axis,对二维数组进行sum,mean,min,max的操作

>>> import numpy as np
>>> arr=np.arange(16).reshape(2,4,2)
>>> arr
array([[[ 0, 1],
[ 2, 3],
[ 4, 5],
[ 6, 7]],

[[ 8, 9],
[10, 11],
[12, 13],
[14, 15]]])

接下来是各种sum,mean,min,max操作

sum如下:

>>> arr.sum(axis=0)
array([[ 8, 10],
[12, 14],
[16, 18],
[20, 22]])
>>> arr.sum(axis=1)
array([[12, 16],
[44, 48]])
>>> arr.sum(axis=2)
array([[ 1, 5, 9, 13],
[17, 21, 25, 29]])

min如下:

>>> arr.min(axis=0)
array([[0, 1],
[2, 3],
[4, 5],
[6, 7]])
>>> arr.min(axis=1)
array([[0, 1],
[8, 9]])
>>> arr.min(axis=2)
array([[ 0, 2, 4, 6],
[ 8, 10, 12, 14]])

通过以上可以发现,通过指定不同的axis,numpy会沿着不同的方向进行操作,如果不设置,则表示对所有的元素进行操作,如果axis=0,则沿着纵轴进行操作,若axis=1则沿着横轴进行操作。但是这只是仅仅对于二维数组而言。但是可以总结为一句话:设axis=i ,则numpy沿着第i个下标变化的方向进行操作,
下面举个三维数组的例子来说明这个道理: 当axis=0时,

>>> arr=np.arange(16).reshape(2,4,2)
>>> arr
array([[[ 0, 1],
[ 2, 3],
[ 4, 5],
[ 6, 7]],

[[ 8, 9],
[10, 11],
[12, 13],
[14, 15]]])
>>> arr.sum(axis=0)
array([[ 8, 10],
[12, 14],
[16, 18],
[20, 22]])

以上例子中,axis=0,首先来看一下,arr的0轴在哪里,arr的shape为(2,4,2),arr的shape下标为(0,1,2),则axis=0对应于数组shape下标的的第一个位置。那么第一个位置的变化方向有几个呢,就要看shape下标对应的数值了,为2,那我们列举这两个变化的方向

000->100 , 001->101
010->110 , 011->111
020->120 , 021->121
030->130 , 031->131

所以将以上两两变化的下标对应的数字进行sum就好了,就得到了上述的结果。
当axis=1时

000->010->020->030    # axis=1的变化方向
001->011->021->031
100->110->120->130
101->111->121->131

得到:
>>> arr.sum(axis=1)
array([[12, 16],
[44, 48]])
下面再来看看np.prod
>>> a1=np.arange(16).reshape(2,4,2)
>>> a1
array([[[ 0, 1],
[ 2, 3],
[ 4, 5],
[ 6, 7]],

[[ 8, 9],
[10, 11],
[12, 13],
[14, 15]]])
>>> np.prod(a1,axis=0)
array([[ 0, 9],
[ 20, 33],
[ 48, 65],
[ 84, 105]])

这下理解到位了,下次运用这个就不会再出错了喽。

下面来研究一下np.concatenate(srcArray,axis ,dstArray)
以前只是用np.oncatenate((a1,a2),axis=0)诸如此类的用法对数组进行拼接,但是从来没有想过如果用np.concatenate((a1),axis=0)这种用法的话会得到什么样的效果。今天与小伙伴讨论了一下,一下子就明白了。下面先给出例子,然后依照例子进行讲解。
实际问题是:

import numpy as np
X=np.arange(620*128*88).reshape(620,1,128,88)
y=np.arange(620)
bottoms=[]
bottoms.append(X)
bottoms.append(y)
X, y = np.concatenate(bottoms[:-1], axis=1), bottoms[-1] # 这一句代码的具体实现过

下面给出具体的小demo:

# 首先 X, y = np.concatenate(bottoms[:-1], axis=1), bottoms[-1] 是对X,y的分开赋值,这毋庸置疑。关键是对于X而言,它的值是由np.concatenate()这个函数如何得到的。
# 下面举个维数比较小的例子;来说明一下。
import numpy as np
X=np.arange(64).reshape(4,1,4,4)
y=np.arange(4)
bottoms=[]
bottoms.append(X)
bottoms.append(y)
result0=np.concatenate(bottoms[:-1], axis=0)
result1=np.concatenate(bottoms[:-1], axis=1)
result2=np.concatenate(bottoms[:-1], axis=2)
result3=np.concatenate(bottoms[:-1], axis=3)
print(bottoms[-1])
print(result0)
print(result0.shape)
print(result1)
print(result1.shape)
print(result2)
print(result2.shape)
print(result3)
print(result3.shape)

对应的输出为:

[0 1 2 3]
[[[[ 0 1 2 3]
[ 4 5 6 7]
[ 8 9 10 11]
[12 13 14 15]]]


[[[16 17 18 19]
[20 21 22 23]
[24 25 26 27]
[28 29 30 31]]]


[[[32 33 34 35]
[36 37 38 39]
[40 41 42 43]
[44 45 46 47]]]


[[[48 49 50 51]
[52 53 54 55]
[56 57 58 59]
[60 61 62 63]]]]
(4, 1, 4, 4)
[[[[ 0 1 2 3]
[ 4 5 6 7]
[ 8 9 10 11]
[12 13 14 15]]]


[[[16 17 18 19]
[20 21 22 23]
[24 25 26 27]
[28 29 30 31]]]


[[[32 33 34 35]
[36 37 38 39]
[40 41 42 43]
[44 45 46 47]]]


[[[48 49 50 51]
[52 53 54 55]
[56 57 58 59]
[60 61 62 63]]]]
(4, 1, 4, 4)
下面再重复两次 :数组内容 数组的shape

下面我们来看一下np.concatenate这个函数的官方文档

numpy操作中的axis的理解
这个函数的输入为 equence of array_like的数组,注意这些数组使用元组括起来的,当做第一个参数,第二个参数是需要拼接的轴(axis).
在代码中的bottoms[:-1]的形状是

numpy操作中的axis的理解
它是一个list,这个list里面有一个array数组,也就是这个list里面就只有一个元素。也就是array数组,但是在np.concatenate中,第一个参数是一个tuple包裹起来的参数
对比:

  1. np.concatenate((a1,a2,…,an), axis=0)
  2. np.concatenate([ a1,a2,…,an], axis=0)
  3. np.concatenate(bottoms[:-1], axis=0)

1、对比可以看出,在np.concatenate()这个函数中,第一参数既可以用tuple来包裹参数,也可以用list来包裹参数传递过去。
2、 那在代码当中,bottoms[:-1]就相当于np.concatenate([ a1 ],axis=0)。
3、因为在np.concatenate()这个函数中,第一个参数至少有两个数组,然后第二个参数指定这两个数组进行拼接的轴是哪个。
4、但是在bottoms[:-1]中只有一个array数组,那要怎么拼接呢,我们试着不同的 axis=0,axis=1, axis=2,axis=3进行拼接,结果发现,指定不同的axis,得到的结果都是一样的。结果都是原数组。即 这个函数对第一个参数如果只有一个数组的话,就是自己和自己拼接,拿自己和自己拼接的到的还是自己。那么最后还是自己。
5、那如果第一个参数有两个呢。举个例子:

>>> a1=np.arange(16).reshape(4,4)
>>> a1
array([[ 0, 1, 2, 3],
[ 4, 5, 6, 7],
[ 8, 9, 10, 11],
[12, 13, 14, 15]])
a2=np.arange(4).reshape(4,1)
>>> a2
array([[0],
[1],
[2],
[3]])
>>> result=np.concatenate((a1,a2),axis=1)
>>> result
array([[ 0, 1, 2, 3, 0],
[ 4, 5, 6, 7, 1],
[ 8, 9, 10, 11, 2],
[12, 13, 14, 15, 3]])
>>> a3=np.arange(4).reshape(1,4)
>>> a3
array([[0, 1, 2, 3]])
>>> result2=np.concatenate((a1,a3),axis=0)
>>> result
array([[ 0, 1, 2, 3, 0],
[ 4, 5, 6, 7, 1],
[ 8, 9, 10, 11, 2],
[12, 13, 14, 15, 3]])

输入的数组按照axis指定的轴进行拼接。完美!!