前言
接触python有一段时间了,但总有一道坎在心中挥之不去,那就是Numpy模块中的axis=-1/0/1/2...
,每每见到axis=-1、axis=0、axis=1、axis=2
等操作,心中真是万马奔腾飘过...
But,有幸看了几篇博文,学到一些“奇淫技巧”,总结整理与大家分享!
铺垫知识
知识点1:python中的列表和numpy中的数组的区别
首先,python内置类型中是没有数组这个概念,有与numpy数组
类似的:列表(list)
和元组(tuple)
其次,列表、元组 与 数组有一个很本质的区别:存储数据类型是否统一
,还有一个显著区别是print(数组 / 列表 元组)
时,是否有逗号将其内元素隔开,即所谓的“是数组是列表元组,print遛一遛”
>>>import numpy as np# numpy 数组 (存储数据类型统一)>>> arr1= np.array([1, 2, 3])# 整型数组>>> arr2= np.array([1, 2,'3'])# 数组中有字符串类型元素,则numpy模块自动将所有元素转为字符串类型>>> print(arr1)[1 2 3]# 整型数组>>> print(arr2)['1''2''3']# 字符串型数组 Tips:python中字符串类型可由:一对单引号'' 或 双引号 "" 构成# python 列表和元组 (存储数据类型可不统一)>>> list1=[1, 2, 3]>>> print(list1)[1, 2, 3]>>> list2=[1, 2,'3']>>> print(list2)[1, 2,'3']>>> tup1=(1, 2, 3)>>> print(tup1)(1, 2, 3)>>> tup2=(1, 2,'3')>>> print(tup2)(1, 2,'3')
知识点2:如何判断数组的维度?
判断数组是是几维,可从左或从右数方括号数目,1个是1维,2个是2维,3个是3维…
如:[[[...]]]
是3维、[[[[[[......]]]]]]
是6维
“括号最大块法”
“括号大法好,见轴(axis)保平安”
1)数组维度与axis的关系
数组维度 | axis取值 |
---|---|
一维数组 | axis = 0 |
二维数组 | axis = 0 ,1 |
三维数组 | axis = 0, 1, 2 |
四维数组 | axis = 0, 1,2, 3 |
N维数组 | axis = 0, 1, 2, 3, … ,N - 1 |
2)axis与“[]”对应关系
在numpy中数组都有[]
标记,其对应关系:axis=0对应最外层的[],axis=1对应第二外层的[],…,axis=n对应第n外层的[]。以三维数组为例,两者关系如下表所示:
axis | [ ] |
---|---|
axis = 0 | [ [ [ ] ]] |
axis = 1 | [[ [ ]] ] |
axis = 2 | [ [[ ] ] ] |
3)括号最大块法:“二步走”
第一步:由axis = value,找对应[]
里的最大单位块
(np.sum()拆掉
此层[],np.argmax()不拆此层[])
第二步:对单位块进行计算
- 当单位块是数值时,直接计算
- 当单位块是数组时,对应下标元素进行计算
那么问题来了,[]
里的最大单位块,最大
是几个意思?(难道不仅最大,还最长? “咳咳,说正事儿…”)
一例胜千言:
[1,2,3],[]里最大的单位块是数值 1 2 3
[[1,2],[3,4]],最外层[]里最大单位块是[1,2] 和 [3,4],第二层[]里最大单位块是1,2 和 3,4
[[[1,2],[3,4]],[[5,6],[7,8]]],最外层[]里最大单位块是[[1,2],[3,4]]和[[5,6],[7,8]],第二层[]里最大单位块是[1,2],[3,4] 和 [5,6],[7,8],第三层[]里最大单位块是1,2 和 3,4 和 5,6 和 7,8
简而言之:某层[]里包裹的最大结构块
问题又来了,单位块是数组时,对应下标元素进行计算?何为对应?
[[1,2],[3,4]]
axis=0,最外层[],仅1个,其里包含两个最大块[1,2]、[3,4],这两个块1和3、2和4即为对应
axis=1,第二层[],有2个,两个[]都为数值,直接计算
[[[1, 2],[3, 4]], [[5, 6],[7, 8]]]
axis=0,最外层[],仅1个,其里包含两个最大块[[1, 2],[3, 4]]、 [[5, 6],[7, 8]],这两个块1和5、2和6、3和7、4和8即为对应
axis=1,第二层[],有2个,第一个[]最大块为:[1, 2]、[3, 4],其中1和3、2和4对应;第二个[]最大块为:[5, 6],[7, 8],其中5和7、6和8对应
axis=2,第三层[],有4个,4个[]内都是数值,直接计算
上述讲解,有没有一种分治法,分而治之的感觉?
即:一个[]只治理一个[]下的元素,多个[]治理多个[]下的元素,互不干扰,共同解决问题!
实例1:np.sum(axis=-1/0/1/2)
一维数组
axis=0
>>>import numpy as np>>> arr= np.array([1, 2, 3])>>> arr.sum(axis= 0)
6
第一步:axis=0对应最外层[],其内最大单位块为:1,2,3,并去掉[]
第二步:单位块是数值,直接计算:1+2+3=6
axis=1
>>> arr= np.array([1, 2, 3])>>> arr.sum(axis= 1)# 越界使用,报错
Traceback(most recent call last):
File"<stdin>", line 1,in<module>
File"D:\Anaconda3\lib\site-packages\numpy\core\_methods.py", line 38,in _sumreturn umr_sum(a, axis, dtype, out, keepdims, initial, where)
numpy.AxisError: axis 1 is out of boundsfor array of dimension 1
由此可知,使用axis时,不要越界,即:N维数组,最大能使用axis=N-1
二维数组
axis=0
>>> arr= np.array([[1, 2],[3, 4]])>>> arr.sum(axis= 0)
array([4, 6])
第一步:axis=0对应最外层[],其内最大单位块为:[1,2] 和 [3,4],并去掉最外层[]
第二步:单位块是数组,两者对应下标元素进行计算,即:[1+3,2+4]=[4,6]
axis=1
>>> arr= np.array([[1, 2],[3, 4]])>>> arr.sum(axis= 1)
array([3, 7])
第一步:axis=1对应第二层[]
,其内最大单位块为:第一[]内: 1,2;第二[]内: 3,4,并去掉第二层[]
第二步:单位块是数值,直接进行计算,即:[1+2,3+4]=[3,7]
三维数组
axis=0
>>> arr= np.array([[[1, 2],[3, 4]],[[5, 6],[7, 8]]])>>> arr
array([[[1, 2],[3, 4]],[[5, 6],[7, 8]]])>>> arr.sum(axis=0)
array([[ 6, 8],[10, 12]])
第一步:axis=0对应最外层[]
,其内最大单位块为:[[1, 2],[3, 4]] 和 [[5, 6],[7, 8]],并去掉最外层[]
第二步:单位块是数组,两者对应下标元素进行计算,即:[[1, 2],[3, 4]] + [[5, 6],[7, 8]] = [[1+5,2+6],[3+7,4+8]] = [[6,8], [10,12]]
axis=1
>>> arr= np.array([[[1, 2],[3, 4]],[[5, 6],[7, 8]]])>>> arr.sum(axis=1)
array([[ 4, 6],[12, 14]])
第一步:axis=1对应第二层[]
,其内最大单位块为:第一个[]: [1, 2]和[3, 4];第二个[]: [5, 6]和[7, 8],并去掉第二层[]
第二步:单位块是数组,两者对应下标元素进行计算,即:第一个[]内:[1+3,2+4],第二个[]内:[5+7,6+8],即:[[1+3,2+4],[5+7, 6+8]] = [[4,6],[12,14]]
axis=2
>>> arr= np.array([[[1, 2],[3, 4]],[[5, 6],[7, 8]]])>>> arr.sum(axis=2)
array([[ 3, 7],[11, 15]])
第一步:axis=1对应第三层[]
,其内最大单位块为:第一个[]:1,2;第二个[]:3,4;第三个[]:5,6;第四个[]:7,8,并去掉第三层[]
第二步:单位块是数值,直接进行计算,即:[[1+2,3+4],[5+6,7+8]] = [[3,7],[11,15]]
axis=-1
>>> arr= np.array([[[1, 2],[3, 4]],[[5, 6],[7, 8]]])>>> arr.sum(axis=-1)
array([[ 3, 7],[11, 15]])
axis=-1,表示在当前数组最后一维度操作,三维数组中axis=0/1/2,那么axis=-1即等价于axis=2,所以其结果与axis=2相同!
实例2:np.argmax(axis=-1/0/1/2)
np.argmax():取数组中元素最大值的下标值
np.argmax()中axis=0/1/2…原理与np.sum()中类似,只是不用“拆括号”了!
一维数组
>>>import numpy as np>>> arr= np.array([3, 4, 6, 9, 1, 2])>>> print(np.argmax(arr))# 默认axis=0
3>>> print(np.argmax(arr, axis=0))
3
二维数组
axis=0
>>> arr= np.array([[3, 6, 6, 2],[4, 7, 11, 2],[5, 9, 1, 3]])>>> arr
array([[ 3, 6, 6, 2],[ 4, 7, 11, 2],[ 5, 9, 1, 3]])>>> np.argmax(arr, axis=0)
array([2, 2, 1, 2], dtype=int64)>>> print(np.argmax(arr, axis=0))[2 2 1 2]
第一步:axis=0对应最外层[]
,其内最大单位块为:[ 3, 6, 6, 2]、 [ 4, 7, 11, 2]和[ 5, 9, 1, 3]
第二步:单位块是数组,两者对应下标元素进行计算,即:argmax([3,4,5])、argmax([6,7,9])、argmax([6,11,1])、argmax([2,2,3]),得到4个最大值索引值:2、2、1、2,得到索引值数组:[2 2 1 2]
axis=1
>>> arr= np.array([[3, 6, 6, 2],[4, 7, 11, 2],[5, 9, 1, 3]])>>> arr
array([[ 3, 6, 6, 2],[ 4, 7, 11, 2],[ 5, 9, 1, 3]])>>> print(np.argmax(arr, axis=1))[1 2 1]
第一步:axis=1对应第二层[]
,其内最大单位块为:3, 6, 6, 2 和 4, 7, 11, 2 和 5, 9, 1, 3
第二步:单位块是数值,直接进行计算,即:argmax([3,6,6,2])、argmax([4,7,11,2])、argmax([5,9,1,3]),得到3个最大值索引值:1、2、1,得到索引数组:[1 2 1]
三维数组
axis=0
>>> arr= np.array([[[1, 5, 5, 2],[9, -6, 2, 8],[-3, 7, -9, 1]],[[-1, 7, -5, 2],[9, 6, 2, 8],[3, 7, 9, 1]],[[21, 6, -5, 2],[9, 36, 2, 8],[2, 7, 66, 1]]])>>> arr
array([[[ 1, 5, 5, 2],[ 9, -6, 2, 8],[-3, 7, -9, 1]],[[-1, 7, -5, 2],[ 9, 6, 2, 8],[ 3, 7, 9, 1]],[[21, 6, -5, 2],[ 9, 36, 2, 8],[ 2, 7, 66, 1]]])>>> print(np.argmax(arr, axis=0))[[2 1 0 0][0 2 0 0][1 0 2 0]]
第一步:axis=0对应最外层[]
,其内最大单位块为:和
和
第二步:单位块是数组,三者
对应下标元素进行计算,如图:
即:argmax([1,-1,21)、argmax([5,7,6])、argmax([5,-5,-5])、argmax([2,2,2])、argmax([9,9,9])、argmax([-6,6,36])…以此类推,得到索引值数组:axis=1
>>> arr
array([[[ 1, 5, 5, 2],[ 9, -6, 2, 8],[-3, 7, -9, 1]],[[-1, 7, -5, 2],[ 9, 6, 2, 8],[ 3, 7, 9, 1]],[[21, 6, -5, 2],[ 9, 36, 2, 8],[ 2, 7, 66, 1]]])>>> print(np.argmax(arr, axis=1))[[1 2 0 1][1 0 2 1][0 1 2 1]]
第一步:axis=1对应第二层[]
,其内最大单位块为:
第一个[]内最大单位块:
第二个[]内最大单位块:
第三个[]内最大单位块:
第二步:各[]内单位块是数组且都为三块,三者对应下标元素进行计算,即:
第一个[]内,三块对应下标,如图:
计算:argmax([1,9,-3)、argmax([5,-6,7])、argmax([5,2,-9])、argmax(2,8,1)
以此类推:第二个[]、第三个[],得到索引值数组:axis=2
>>> arr
array([[[ 1, 5, 5, 2],[ 9, -6, 2, 8],[-3, 7, -9, 1]],[[-1, 7, -5, 2],[ 9, 6, 2, 8],[ 3, 7, 9, 1]],[[21, 6, -5, 2],[ 9, 36, 2, 8],[ 2, 7, 66, 1]]])>>> print(np.argmax(arr, axis=2))[[1 0 1][1 0 2][0 1 2]]
第一步:axis=2对应第三层[]
,其内最大单位块为:
1,5,5,2
9,-6,2,8
-3,7,-9,1
-1,7,-5,2
9,6,2,8
3,7,9,1
21,6,-5,2
9,36,2,8
2,7,66,1
第二步:单位块是数值,直接进行计算,即:
argmax([1,5,5,2])
argmax([9,-6,2,8])
argmax([-3,7,-9,1])
argmax([-1,7,-5,2])
…
以此类推,得到索引数组:axis=-1
>>> print(np.argmax(arr, axis=-1))[[1 0 1][1 0 2][0 1 2]]
axis=-1,表示在当前数组最后一维度操作,三维数组中axis=0/1/2,那么axis=-1即等价于axis=2,所以其结果与axis=2相同!