前言
numpy和Pandas是数据处理中常用的库,numpy和Pandas许多函数都有axis这个参数,传入axis参数可以指定在哪个轴上操作,但是使用axis到底该指定哪个轴,这带了很多的困惑。下面我们就来分析一下,axis是怎么指定不同的轴的,以及指定不同的轴,是怎样操作的。Pandas保持了Numpy对关键字axis的用法,在此我们以numpy为例进行解释。
shape与axis
numpy的array有个shape属性,如:
import numpy as np
np.random.seed(123)
x=np.random.randint(0,5,[2,3,2])
print (x)
print (x.shape)
[[[2 4]
[2 1]
[3 2]]
[[3 1]
[1 0]
[1 1]]]
(2, 3, 2)
可以看到生成的是一个三维的随机数组,axis=0就对应shape的用第0个元素对应的维度,axis=1对应shape的用第1个元素对应的维度,axis=2对应shape的用第2个元素对应的维度。即 axis=0,1,2 表示从外到内的维度。(2, 3, 2) 表示包含2个三行两列的数组。
numpy中的axis的设置参数与数组的shape有关
例如一个shape(3,2,4)的数组,代表一个三维数组,要注意的是这里的维度与物理学的维度的理解是不太一样的
axis = 0时,就相当于所求的数组的结果变成shape(2,4)
axis = 1时,数组的结果shape(3,4)
axis = 2时,数组的结果shape(3,2)
这里应该看出来了,当axis=n的时候shape中相应的索引就会被去除,数组发生了降维,那么是如何降维的呢?首先要清楚shape里的数字都代表什么意义:
3代表这个numpy数组里嵌套着3个数组(有三层), 2代表其中每个数组的行数,3代表其中每个数组的列数。
以二维数组为例理解axis
>>>df = pd.DataFrame([[1, 1, 1, 1], [2, 2, 2, 2], [3, 3, 3, 3]], \
columns=["col1", "col2", "col3", "col4"])
>>>df
col1 col2 col3 col4
0 1 1 1 1
1 2 2 2 2
2 3 3 3 3
如果我们调用df.mean(axis=1),我们将得到按行计算的均值
>>> df.mean(axis=1)
0 1
1 2
2 3
然而,如果我们调用 df.drop((name, axis=1),我们实际上删掉了一列,而不是一行:
>>> df.drop("col4", axis=1)
col1 col2 col3
0 1 1 1
1 2 2 2
2 3 3 3
其实问题理解axis有问题,df.mean其实是在每一行上取所有列的均值,而不是保留每一列的均值。也许简单的来记就是axis=0代表往跨行(down),而axis=1代表跨列(across),作为方法动作的副词(译者注)
换句话说:
- 使用0值表示沿着每一列或行标签\索引值向下执行方法
- 使用1值表示沿着每一行或者列标签模向执行对应的方法
下图代表在DataFrame当中axis为0和1时分别代表的含义:
axis参数作用方向图示。另外,记住,Pandas保持了Numpy对关键字axis的用法,用法在Numpy库的词汇表当中有过解释:轴用来为超过一维的数组定义的属性,二维数据拥有两个轴:第0轴沿着行的垂直往下,第1轴沿着列的方向水平延伸。
所以问题当中第一个列子 df.mean(axis=1)代表沿着列水平方向计算均值,而第二个列子df.drop(name, axis=1) 代表将name对应的列标签(们)沿着水平的方向依次删掉。即df.mean(axis=1)表示一行一行的计算均值,df.drop(name, axis=1)表示一行一行的将name列删掉。还可以这样理解,axis等于那个维度代表操作在哪个维度上进行,操作后该维度消失(变成1)。如df.mean(axis=1),axis=1表示均值操作在列上进行(跨列操作),即按照行相加求均值,操作后变成一列。axis指定哪个维度表示跨哪个维度进行操作。
以三维数组为例理解axis
import numpy as np
np.random.seed(123)
x=np.random.randint(0,5,[2,3,2])
print (x)
print (x.max(axis=0))
print (x.sum(axis=0))
[[[2 4]
[2 1]
[3 2]]
[[3 1]
[1 0]
[1 1]]]
[[3 4]
[2 1]
[3 2]]
[[5 5]
[3 1]
[4 3]]
x数组的shape为(2,3,2),3代表这个numpy数组里嵌套着3个数组(有三层), 2代表其中每个数组的行数,3代表其中每个数组的列数。x.max(axis=0)
去掉第0个维度,得出的肯定是一个3行2列的数组。axis=0 表示跨第0个维度操作,其他维度保持不变。
>>> print (x.max(axis=1))
[[3 4]
[3 1]]
>>> print (x.sum(axis=1))
[[7 7]
[5 2]]
x.max(axis=1)
去掉第1个维度,得出的肯定是一个2行2列的数组。axis=1 表示跨第1个维度操作,其他维度保持不变。
>>> print (x.max(axis=2))
[[4 2 3]
[3 1 1]]
>>> print (x.sum(axis=2))
[[6 3 5]
[4 1 2]]
x.max(axis=2)
去掉第2个维度,得出的肯定是一个2行3列的数组。axis=2 表示跨第2个维度操作,其他维度保持不变。