轴在熊猫中是什么意思?

下面是我生成一个数据框架的代码:

import pandas as pd
import numpy as np


dff = pd.DataFrame(np.random.randn(1,2),columns=list('AB'))

然后我得到了数据框架:

+------------+---------+--------+
|            |  A      |  B     |
+------------+---------+---------
|      0     | 0.626386| 1.52325|
+------------+---------+--------+

当我输入命令时:

dff.mean(axis=1)

我得到:

0    1.074821
dtype: float64

根据pandas的参考,axis=1代表列,我希望命令的结果是

A    0.626386
B    1.523255
dtype: float64

我的问题是:轴在熊猫中是什么意思?

417088 次浏览

它指定了计算平均值的轴numpy.mean0。默认为axis=0。这与axis被指定为numpy.mean1时的numpy.mean用法是一致的(在numpy.mean中,默认情况下axis==None,它计算扁平数组上的平均值),其中axis=0沿着numpy.mean2(即熊猫中的numpy.mean3), axis=1沿着numpy.mean4。为了增加清晰度,可以选择指定axis='index'(而不是axis=0)或axis='columns'(而不是axis=1)。

+------------+---------+--------+
|            |  A      |  B     |
+------------+---------+---------
|      0     | 0.626386| 1.52325|----axis=1----->
+------------+---------+--------+
|         |
| axis=0  |
↓         ↓

熊猫的设计师韦斯•麦金尼(Wes McKinney)曾大量从事金融数据方面的工作。将列视为股票名称,将指数视为每日价格。然后,您可以猜测关于此财务数据的默认行为是什么(即axis=0)。axis=1可以简单地认为是“另一个方向”。

例如,统计函数,如mean()sum()describe()count()都默认为按列,因为对每只股票执行它们更有意义。sort_index(by=)也默认为column。fillna(method='ffill')将填充一个列,因为它是相同的股票。dropna()默认为row,因为您可能只是想丢弃当天的价格,而不是丢弃该股票的所有价格。

类似地,方括号索引指的是列,因为更常见的是选择股票而不是选择日期。

对我来说,最简单的理解方法是讨论你是在为每一列(axis = 0)还是每一行(axis = 1)计算统计数据。如果你计算一个统计数据,比如一个平均值,使用axis = 0,你会得到每一列的统计数据。如果每个观察值是一行,每个变量是一列,你就会得到每个变量的均值。如果你设置了axis = 1,那么你将为每一行计算你的统计数据。在我们的例子中,您将获得所有变量中每个观察值的平均值(也许您想要相关度量值的平均值)。

axis = 0: by column = column-wise =沿着行

axis = 1:通过row = row-wise =沿着列

axis指数组的维数,在pd.DataFrames的例子中,axis=0是指向下方的维数,而axis=1是指向右侧的维数。

想象一个形状为(3,5,7)ndarray

a = np.ones((3,5,7))

a是一个三维的ndarray,即它有3轴(“axes”是“axis”的复数)。a的配置看起来像3片面包,每片面包的尺寸是5 × 7。a[0,:,:]将指向第0个切片,a[1,:,:]将指向第1个切片,等等。

a.sum(axis=0)将沿着a的第0个轴应用sum()。你将添加所有的切片,最终得到一个形状(5,7)的切片。

a.sum(axis=0)等价于

b = np.zeros((5,7))
for i in range(5):
for j in range(7):
b[i,j] += a[:,i,j].sum()

ba.sum(axis=0)看起来都是这样的

array([[ 3.,  3.,  3.,  3.,  3.,  3.,  3.],
[ 3.,  3.,  3.,  3.,  3.,  3.,  3.],
[ 3.,  3.,  3.,  3.,  3.,  3.,  3.],
[ 3.,  3.,  3.,  3.,  3.,  3.,  3.],
[ 3.,  3.,  3.,  3.,  3.,  3.,  3.]])

pd.DataFrame中,轴的工作方式与__abc1相同:axis=0将对每一列应用sum()或任何其他约简函数。

注意:在@zhangxaochen的回答中,我发现短语“沿着行”和“沿着列”有点令人困惑。axis=0应该是指“沿着每一列”,而axis=1是指“沿着每一行”。

轴在编程中是形状元组中的位置。这里有一个例子:

import numpy as np


a=np.arange(120).reshape(2,3,4,5)


a.shape
Out[3]: (2, 3, 4, 5)


np.sum(a,axis=0).shape
Out[4]: (3, 4, 5)


np.sum(a,axis=1).shape
Out[5]: (2, 4, 5)


np.sum(a,axis=2).shape
Out[6]: (2, 3, 5)


np.sum(a,axis=3).shape
Out[7]: (2, 3, 4)

轴上的均值将导致该维度被移除。

参考原题,dff形状为(1,2)。使用axis=1将形状更改为(1,)。

这些答案确实有助于解释这一点,但对于非程序员(例如,像我这样第一次在数据科学课程背景下学习Python的人)来说,它仍然不是完全直观的。我仍然发现使用术语“沿着”或“每个”wrt的行和列是令人困惑的。

对我来说更有意义的是这样说:

  • 轴0将作用于每个COLUMN中的所有row
  • 轴1将作用于每个ROW中的所有COLUMNS

0轴上的均值是每列中所有行的均值,1轴上的均值是每行中所有列的均值。

从根本上说,这和@zhangxaochen和@Michael的意思是一样的,只是用一种更容易让我内化的方式。

轴= 0表示从上到下 Axis = 1表示从左到右

sums[key] = lang_sets[key].iloc[:,1:].sum(axis=0)

给定的例子是取column == key中所有数据的和。

数组被设计成所谓的轴=0和行垂直定位,而轴=1和列水平定位。Axis指的是数组的尺寸。 插图

.

让我们想象(你会永远记住), enter image description here < / p >

熊猫:

  1. 轴=0表示沿着“索引”。它是row-wise操作

假设对dataframe1 &执行concat()操作;dataframe2, 我们将采用dataframe1 &从dataframe1中取出第一行并放入新的DF中,然后从dataframe1中取出另一行并放入新的DF中,我们重复这个过程,直到我们到达dataframe1的底部。然后,我们对dataframe2进行相同的处理

基本上,将dataframe2堆叠在dataframe1之上,反之亦然。

在桌子或地板上堆一堆书

  1. 轴=1表示沿着“列”。它是列操作。

假设对dataframe1 &执行concat()操作;dataframe2, 我们将取出第一个完整的列(a.k.)。a第1系列)的dataframe1并放置到新的DF中,然后我们取出dataframe1的第二列并保持与它相邻(横向),我们必须重复这个操作,直到所有列都完成。然后,我们在dataframe2上重复相同的过程。 基本上, . .

把书摆放在书架上。

更重要的是,与矩阵相比,数组更好地表示嵌套的n维结构!所以下面可以帮助你更直观地看到轴是如何在一维以上的情况下发挥重要作用的。此外,你实际上可以打印/写入/绘制/可视化任何n-dim数组,但在矩阵表示(3-dim)中书写或可视化相同的内容在超过3维的纸张上是不可能的。

enter image description here

我的想法是:Axis = n,其中n = 0,1等意味着矩阵沿该轴折叠(折叠)。所以在一个二维矩阵中,当你沿着0(行)折叠时,你实际上是一次对一列进行操作。对于高阶矩阵也是如此。

这与对矩阵中维数的正常引用不同,其中0 ->行和1 ->列。对于N维数组中的其他维度也是如此。

这是基于@Safak的回答。 理解pandas/numpy中的轴的最好方法是创建一个3d数组,并沿着3个不同的轴检查sum函数的结果
 a = np.ones((3,5,7))

A将是:

    array([[[1., 1., 1., 1., 1., 1., 1.],
[1., 1., 1., 1., 1., 1., 1.],
[1., 1., 1., 1., 1., 1., 1.],
[1., 1., 1., 1., 1., 1., 1.],
[1., 1., 1., 1., 1., 1., 1.]],


[[1., 1., 1., 1., 1., 1., 1.],
[1., 1., 1., 1., 1., 1., 1.],
[1., 1., 1., 1., 1., 1., 1.],
[1., 1., 1., 1., 1., 1., 1.],
[1., 1., 1., 1., 1., 1., 1.]],


[[1., 1., 1., 1., 1., 1., 1.],
[1., 1., 1., 1., 1., 1., 1.],
[1., 1., 1., 1., 1., 1., 1.],
[1., 1., 1., 1., 1., 1., 1.],
[1., 1., 1., 1., 1., 1., 1.]]])

现在检查数组中每个轴上元素的和:

 x0 = np.sum(a,axis=0)
x1 = np.sum(a,axis=1)
x2 = np.sum(a,axis=2)

会给你以下结果:

   x0 :
array([[3., 3., 3., 3., 3., 3., 3.],
[3., 3., 3., 3., 3., 3., 3.],
[3., 3., 3., 3., 3., 3., 3.],
[3., 3., 3., 3., 3., 3., 3.],
[3., 3., 3., 3., 3., 3., 3.]])


x1 :
array([[5., 5., 5., 5., 5., 5., 5.],
[5., 5., 5., 5., 5., 5., 5.],
[5., 5., 5., 5., 5., 5., 5.]])


x2 :
array([[7., 7., 7., 7., 7.],
[7., 7., 7., 7., 7.],
[7., 7., 7., 7., 7.]])

我对熊猫还是个新手。但这是我对熊猫轴的理解:


__abc0 __abc1 __abc2 __abc3


0列行向下|


1行列向右——>


因此,要计算一列的均值,该列应该是常数,但它下面的行可以改变(不同的),因此它是axis=0。

类似地,要计算一行的平均值,特定的行是常数,但它可以遍历不同的列(不同的), axis=1。

我是这样理解的:

例如,如果你的操作需要从数据帧中的Left to right/从右到左遍历,你显然是在合并列。你在不同的列上操作。 这是轴= 1

例子

df = pd.DataFrame(np.arange(12).reshape(3,4),columns=['A', 'B', 'C', 'D'])
print(df)
A  B   C   D
0  0  1   2   3
1  4  5   6   7
2  8  9  10  11


df.mean(axis=1)


0    1.5
1    5.5
2    9.5
dtype: float64


df.drop(['A','B'],axis=1,inplace=True)


C   D
0   2   3
1   6   7
2  10  11

这里需要注意的是,我们是在列上操作

类似地,如果你的操作需要从数据帧中的从上到下/从下到上遍历,你是在合并行。这是轴= 0

让我们看看维基上的表格。这是国际货币基金组织对2010年至2019年前十大国家GDP的估计。 enter image description here < / p >

如果你想计算每个国家过去十年(2010-2019)的平均GDP,你需要做,df.mean(axis=1)。例如,如果你想计算美国从2010年到2019年的平均GDP, df.loc['United States','2010':'2019'].mean(axis=1)

如果我想计算所有国家每年的平均(平均)GDP,你需要做,df.mean(axis=0)。例如,如果你想计算2015年美国、中国、日本、德国和印度的平均GDP, df.loc['United States':'India','2015'].mean(axis=0)
以上代码只有在使用set_index方法将“国家(或附属领土)”列设置为索引后才能工作。

正确使用axis=的问题在于它在两种主要不同情况下的使用:

  1. 用于计算累计值重新安排数据(例如排序)。
  2. 对于操纵 ("play "with) 实体(例如dataframes)。

这个答案背后的主要思想是为了避免混淆,我们选择数量的名字来指定特定的轴以更清晰、直观和描述性的为准。

Pandas基于NumPy, NumPy基于数学,特别是n维矩阵。下面是三维空间中数学中常用的轴的名称:

enter image description here 此图片仅用于记忆轴的序数:

  • 0为x轴,
  • 1为y轴,和
  • z轴为2

z轴仅用于面板;对于dataframes,我们将把我们的兴趣限制在绿色,二维基本平面x轴(0,垂直)y轴(1,水平)。

enter image description here 这都是数字作为axis=参数的潜在值

坐标轴的的名字'index'(你可以使用别名'rows')和'columns',对于这个解释,这些名称和序数之间的关系并不重要(坐标轴),因为每个人都知道“rows"“columns"是什么意思(每个人都知道在这里 -我想-知道熊猫中的“index"是什么意思)。

现在,我的建议是

  1. 如果你想要计算累积值,你可以从位于沿轴0(或沿轴1)的值计算它-使用axis=0(或axis=1)。

    类似地,如果你想重新排列的价值观,使用轴的轴数沿着这条都是定位数据进行重新排列(例如,用于排序)。

  2. 如果你想操作(例如连接) 实体(例如dataframes) -使用axis='index'(同义词:axis='rows')或axis='columns'分别指定产生的变化 - 指数 ()或axis='rows'0。
    (对于连接,你将分别获得更长的索引(=更多的行)更多的列)

我认为还有另一种理解方式。

对于np。数组,如果我们想要消除列,我们使用axis = 1;如果我们想消除行,我们使用axis = 0。

np.mean(np.array(np.ones(shape=(3,5,10))),axis = 0).shape # (5,10)
np.mean(np.array(np.ones(shape=(3,5,10))),axis = 1).shape # (3,10)
np.mean(np.array(np.ones(shape=(3,5,10))),axis = (0,1)).shape # (10,)

对于pandas对象,axis = 0表示按行操作,axis = 1表示按列操作。这与numpy的定义不同,我们可以检查numpy.docpandas.doc的定义

记住轴1(列)与轴0(行)的简单方法之一是您期望的输出。

  • 如果你希望每行都有输出,使用axis='columns',
  • 另一方面,如果你想为每一列输出,你可以使用axis='rows'。

我将明确避免使用“行-wise”或“沿列”,因为人们可能会以完全错误的方式解释它们。

类比。直观地,你会期望pandas.DataFrame.drop(axis='column')从N列中删除一列,并给你(N - 1)列。所以你现在可以不关注rows(并从你的英语字典中删除row这个单词)。反之亦然,drop(axis='row')作用于行。

以同样的方式,sum(axis='column')工作在多个列上,并给你一个列。类似地,sum(axis='row')的结果是1行。这与其最简单的定义形式是一致的,即将一组数字简化为一个数字。

一般来说,使用axis=column,你会看到列,处理列,并获得列。忘记行。

使用axis=row,改变透视图并处理行。

0和1只是“行”和“列”的别名。这是矩阵下标的惯例。

在过去的一个小时里,我也一直在试着求出坐标轴。上述所有答案中的语言,以及文档都没有任何帮助。

要回答我现在理解的问题,在Pandas中,axis = 1或0意味着在应用函数时希望保持哪个轴头不变。

注意:当我说标题时,我指的是索引名

扩展你的例子:

+------------+---------+--------+
|            |  A      |  B     |
+------------+---------+---------
|      X     | 0.626386| 1.52325|
+------------+---------+--------+
|      Y     | 0.626386| 1.52325|
+------------+---------+--------+

对于轴=1=列:我们保持列标题不变,并通过改变数据应用平均值函数。 为了演示,我们保持列标题不变:

+------------+---------+--------+
|            |  A      |  B     |

现在我们填充A和B值的一个集合,然后找到平均值

|            | 0.626386| 1.52325|

然后我们填充下一组A和B值,并找到平均值

|            | 0.626386| 1.52325|
类似地,对于axis=rows,我们保持行标题不变,并不断更改数据: 为了演示,首先修正行标题:

+------------+
|      X     |
+------------+
|      Y     |
+------------+

现在填充第一组X和Y值,然后求平均值

+------------+---------+
|      X     | 0.626386
+------------+---------+
|      Y     | 0.626386
+------------+---------+

然后填充下一组X和Y值,然后找到平均值:

+------------+---------+
|      X     | 1.52325 |
+------------+---------+
|      Y     | 1.52325 |
+------------+---------+

总之,

当axis=columns时,将修复列标题并更改数据,这些数据将来自不同的行。

当axis=rows时,您将修复行标题并更改数据,这些数据将来自不同的列。

enter image description here

enter image description here

axis=1,它将给出行和,keepdim =True将保持2D维度。

.

.

这里的许多答案对我帮助很大!

如果你对Python中的axis和R中的MARGIN(比如apply函数)的不同行为感到困惑,你可以找到我写的一篇感兴趣的博客文章:https://accio.github.io/programming/2020/05/19/numpy-pandas-axis.html

从本质上讲:

  • 有趣的是,它们的行为在三维数组中比在二维数组中更容易理解。
  • 在Python包numpypandas中,sum中的axis参数实际上指定numpy来计算所有可以以数组[0,0,…]形式获取的值的平均值。,我,…, 0]遍历所有可能的值。重复这个过程,i的位置固定,其他维度的指标一个接一个地变化(从最极右的元素开始)。结果是一个n-1维数组。
  • 在R中,edges参数让apply函数计算所有可以以数组[,…]形式获取的值的平均值。,我,…,],其中我迭代所有可能的值。当所有i值都被迭代时,该过程不会重复。因此,结果是一个简单的向量。

例如,如果你使用df.shape,那么你将得到一个元组,其中包含行数&数据帧中的列作为输出。

In [10]: movies_df.shape
Out[10]: (1000, 11)

在上面的例子中,有1000行&电影数据帧中的11列,其中'row'被提到在索引0位置&'column'在元组的索引1位置。因此'axis=1'表示列&'axis=0'表示行。

学分:Github

我以前也很困惑,但我记得是这样的。

它指定将更改的数据帧的维度,或者将在其上执行操作。

让我们用一个例子来理解这一点。 我们有一个数据帧df,它的形状为(5,10),这意味着它有5行10列

现在,当我们执行df.mean(axis=1)时,它意味着维度1将被改变,这意味着它将具有相同的行数,但不同的列数。因此得到的结果将是(5,1)的形状。

类似地,如果我们执行df.mean(axis=0),这意味着维度0将被改变,这意味着行数将被改变,但列数将保持不变,因此结果将是形状(1,10)。

试着把这个和问题中提供的例子联系起来。

在Pandas上有两种最常见的axis用法:

  1. 用作索引,如df.iloc[0, 1]
  2. 用作函数内的参数,如df.mean(axis=1)

当使用作为索引时,我们可以解释axis=0代表行,axis=1代表列,即df.iloc[rows, columns]。因此,df.iloc[0, 1]意味着从第0行和第1列中选择数据,在这种情况下,它返回1.52325。

当使用作为参数时,axis=0表示垂直跨行选择对象,而axis=1表示水平跨列选择对象。

axis

因此,df.mean(axis=1)表示水平计算跨列的平均值,它返回:

0    1.074821
dtype: float64

轴的一般用途是用于选择要操作的特定数据。而理解轴的关键,是分离“选择”的过程;和“;operation"

让我们用1个额外的情况来解释:df.drop('A', axis=1)

  1. 操作是df.drop(),它需要目标对象的名称 列,在这里是A。它和df.mean()不一样
  2. 选择的是列的名称,而不是列的数据内容。由于所有列名都水平排列在列之间,因此我们使用axis=1来选择name对象。

简而言之,我们最好把“选择”和“选择”分开。和“;operation"对以下方面有清晰的认识:

  1. 选择什么对象
  2. 是怎么安排的

我相信,正确的答案应该是“这很复杂"

< p > [1]术语“轴心”;不同的人会产生不同的心理印象
假设y轴,它应该是一个垂直的图像。然而,现在考虑一条垂直线x=0。它也是一条垂直线,但它在x轴上的值是解决

类似地,当我们说axis='index'(意为axis=0)时,我们说的是&;vertical&;索引所在的方向?或那一系列的数据解决由一个索引值?熊猫往往意味着第一个意思,垂直方向。

熊猫本身也不是100%一致的,看看下面的例子,它们几乎有相同的共同主题:

# [1] piling dfs
pd.concat([df0, df1], axis='index')
# adding dfs on top of each other vertically like pilling up a column,
# but, we will use the word 'index'


# [2] for every column in df: operate on it
df.apply(foo, axis='index')
df.mean('A', axis='index')
a_boolean_df.all(axis='index')
# apply an operation to a vertical slice of data, ie. a column,
# then apply the same operation to the next column on the right
# then to the right again... until the last column
# but, we will use the word 'index'


# [3] delete a column or row of data
df.drop(axis='index', ...)
df.dropna(axis='index', ...)
# this time, we are droping an index/row, a horizontal slice of data.
# so OBVIOUSLY we will use the word 'index'


# [4] drop duplicate
df.drop_duplicates(subset=['mycolumn0', 'mycolumn1']...)
# thank God we don't need to deal with the "axis" bs in this
实际上,我们不需要记住axis=0, axis=1代表什么。
有时,轴可以是一个元组:例如__abc0我们如何理解这样多个dim轴?< / p >

我发现如果我们理解Python slice [:]是如何工作的,它会更容易。

假设我们有一个1d数组: a = [ 0, 1, 0 ] < / p >
a[:] # select all the elements in array a

假设我们有一个2d数组:

M = [[0, 0, 1],
[1, 0, 0],
[0, 2, 1],
[2, 0, 2],
[3, 1, 0]]
M[1,:] # M[0]=1, M[1]=* --> [1, 0, 0]
M[:,2] # M[0]=*, M[1]=2 --> [1, 0, 1, 2, 0]
M[:,:] # M[0]=*, M[1]=* --> all the elements in M are selected

当计算时:

np.sum(M, axis=0) # [sum(M[:,0]), sum(M[:,1]), sum(M[:,2])]
np.sum(M, axis=1) # [sum(M[0,:]), sum(M[1,:]), sum(M[2,:]), sum(M[3,:]), sum(M[4,:])]
np.sum(M, axis=-1) # -1 means last dim, it's the same with np.sum(M, axis=1)
np.sum(M, axis=(0,1)) # sum(M[:,:])

规则很简单,计算时将axis中指定的dim替换为:

有一件重要的事情要记住,当你使用诸如mean, median等函数时,你基本上是在执行numpy聚合。可以将聚合看作是获得最终的单个输出,该输出可以是列输出、行输出,也可以是整个数据集的单个数字。

所以当我们说数组中的聚合,比如numpy.sum(data, axis = 0),我们真正的意思是我们想要移除那个特定的轴(这里是0轴)。

Numpy Axis插图

对于这个特定的数据集,如果我们通过axis = 0来计算和,我们实际上感兴趣的是删除(聚集)零轴。一旦我们移除零轴,沿着零轴的聚合将导致[1,4,3]等于8,[2,3,6]等于11,[5,7,9]等于21。类似的逻辑可以扩展到axis = 1。

对于drop, concat和其他一些函数,我们实际上不是

我用于直觉的心智模型:

假设当轴= 0时,我们在第一列的每个单元格中放置了袋鼠/青蛙;如果轴= 1,则沿着第一行放置了袋鼠/青蛙。

案例:当轴= 0

First Step

把加绿色的形状想象成青蛙。

轴0表示沿着行移动

总结:假设我们正在计算和,那么首先它们将计算它们的位置(r1c1, r2c1, r3c1)[1,4,3] =[8]的和。然后它们的下一个移动也是沿着轴为0的那一行。他们的新位置在下一张图片中(下图)。

下降:如果沿着行他们遇到任何NaN在(r1c1, r2c1, r3c1),他们将删除对应的行作为轴线= 0

Second Step

总结:现在再次,它们将计算它们的位置(r1c2, r2c2, r3c2)[2,3,6] =[11],类似地,它们将沿着行向前移动一步,并计算第三列[21]的和。

下降:如果沿着行他们遇到任何NaN在(r1c2, r2c2, r3c2),他们将删除对应的行作为axis = 0。类似的逻辑可以扩展到不同的轴和额外的行/列。

Third Step