Pandas Dataframe / Numpy Array“axis”定义中的歧义

rks48beu  于 10个月前  发布在  其他
关注(0)|答案(7)|浏览(66)

我一直对python轴的定义方式以及它们是引用DataFrame的行还是列感到非常困惑。下面的代码:

>>> 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

有人能帮助我理解pandas/numpy/scipy中的“axis”是什么意思吗?
顺便说一下,DataFrame.mean可能定义错误。在DataFrame.mean的文档中说,axis=1应该是指列的平均值,而不是行的平均值。

8aqjt8rx

8aqjt8rx1#

也许最简单的方法是记住 0=down1=across
这意味着:

  • 使用axis=0将一个方法应用到每一列或行标签(索引)。
  • 使用axis=1在每行或列标签上应用一个方法。

下面的图片显示了每个轴引用的DataFrame的各个部分:

记住Pandas遵循NumPy对单词axis的使用也很有用。在NumPy的glossary of terms中解释了该用法:
轴是为具有多个维度的数组定义的。一个二维数组有两个对应的轴:第一条垂直向下穿过行(轴0),第二条水平穿过列(轴1)。[* 我的强调 *]
因此,关于问题中的方法df.mean(axis=1),似乎定义正确。它取 * 水平跨列 *(即,沿着每一行)的条目的平均值。另一方面,df.mean(axis=0)将是一个垂直 * 跨行向下 * 的操作。
类似地,df.drop(name, axis=1)指的是对列标签的操作,因为它们直观地穿过水平轴。指定axis=0将使该方法作用于行。

qoefvg9y

qoefvg9y2#

已经有正确的答案了,但我给予你另一个> 2维的例子。

*参数axis表示 * 要更改的轴

例如,考虑有一个维数为 a x B x c 的三角形。

  • df.mean(axis=1)返回一个尺寸为 a x 1 x c 的 Dataframe 。
  • df.drop("col4", axis=1)返回维度为 a x(B-1)x c 的 Dataframe 。

这里,axis=1表示第二个轴,即b,因此在这些示例中,b的值将发生变化。

flmtquvp

flmtquvp3#

另一种解释方式:

// Not realistic but ideal for understanding the axis parameter 
df = pd.DataFrame([[1, 1, 1, 1], [2, 2, 2, 2], [3, 3, 3, 3]],
                  columns=["idx1", "idx2", "idx3", "idx4"],
                  index=["idx1", "idx2", "idx3"]
                 )

---------------------------------------1
|          idx1  idx2  idx3  idx4
|    idx1     1     1     1     1
|    idx2     2     2     2     2
|    idx3     3     3     3     3
0

关于df.drop(轴表示位置)

A: I wanna remove idx3.
B: **Which one**? // typing while waiting response: df.drop("idx3",
A: The one which is on axis 1
B: OK then it is >> df.drop("idx3", axis=1)

// Result
---------------------------------------1
|          idx1  idx2     idx4
|    idx1     1     1     1
|    idx2     2     2     2
|    idx3     3     3     3
0

关于df.apply(轴表示方向)

A: I wanna apply sum.
B: Which direction? // typing while waiting response: df.apply(lambda x: x.sum(),
A: The one which is on *parallel to axis 0*
B: OK then it is >> df.apply(lambda x: x.sum(), axis=0)

// Result
idx1    6
idx2    6
idx3    6
idx4    6
hof1towb

hof1towb4#

应该更广泛地知道,字符串别名**'index''columns'可以用来代替整数0/1。别名更加明确,帮助我记住计算是如何发生的。“index”的另一个别名是“rows”**。
当使用axis='index'时,计算会发生在列的下方,这很令人困惑。但是,我记得它得到的结果与另一行大小相同。
让我们在屏幕上得到一些数据,看看我在说什么:

df = pd.DataFrame(np.random.rand(10, 4), columns=list('abcd'))
          a         b         c         d
0  0.990730  0.567822  0.318174  0.122410
1  0.144962  0.718574  0.580569  0.582278
2  0.477151  0.907692  0.186276  0.342724
3  0.561043  0.122771  0.206819  0.904330
4  0.427413  0.186807  0.870504  0.878632
5  0.795392  0.658958  0.666026  0.262191
6  0.831404  0.011082  0.299811  0.906880
7  0.749729  0.564900  0.181627  0.211961
8  0.528308  0.394107  0.734904  0.961356
9  0.120508  0.656848  0.055749  0.290897

当我们想取所有列的平均值时,我们使用axis='index'来得到以下结果:

df.mean(axis='index')
a    0.562664
b    0.478956
c    0.410046
d    0.546366
dtype: float64

同样的结果将通过以下方式得到:

df.mean() # default is axis=0
df.mean(axis=0)
df.mean(axis='rows')

要使用从左到右的操作来获取行,请使用axis ='columns'.我记得它的想法是,一个额外的列可能会添加到我的DataFrame:

df.mean(axis='columns')
0    0.499784
1    0.506596
2    0.478461
3    0.448741
4    0.590839
5    0.595642
6    0.512294
7    0.427054
8    0.654669
9    0.281000
dtype: float64

同样的结果将通过以下方式得到:

df.mean(axis=1)

新增一行,axis=0/index/rows

让我们使用这些结果添加其他行或列来完成说明。因此,每当使用axis = 0/index/rows时,就像获取DataFrame的新行一样。让我们添加一行:

df.append(df.mean(axis='rows'), ignore_index=True)

           a         b         c         d
0   0.990730  0.567822  0.318174  0.122410
1   0.144962  0.718574  0.580569  0.582278
2   0.477151  0.907692  0.186276  0.342724
3   0.561043  0.122771  0.206819  0.904330
4   0.427413  0.186807  0.870504  0.878632
5   0.795392  0.658958  0.666026  0.262191
6   0.831404  0.011082  0.299811  0.906880
7   0.749729  0.564900  0.181627  0.211961
8   0.528308  0.394107  0.734904  0.961356
9   0.120508  0.656848  0.055749  0.290897
10  0.562664  0.478956  0.410046  0.546366

新增一列,axis=1/columns

类似地,当axis=1/columns时,它将创建可以轻松地放入自己的列中的数据:

df.assign(e=df.mean(axis='columns'))

          a         b         c         d         e
0  0.990730  0.567822  0.318174  0.122410  0.499784
1  0.144962  0.718574  0.580569  0.582278  0.506596
2  0.477151  0.907692  0.186276  0.342724  0.478461
3  0.561043  0.122771  0.206819  0.904330  0.448741
4  0.427413  0.186807  0.870504  0.878632  0.590839
5  0.795392  0.658958  0.666026  0.262191  0.595642
6  0.831404  0.011082  0.299811  0.906880  0.512294
7  0.749729  0.564900  0.181627  0.211961  0.427054
8  0.528308  0.394107  0.734904  0.961356  0.654669
9  0.120508  0.656848  0.055749  0.290897  0.281000

您似乎可以看到所有具有以下私有变量的别名:

df._AXIS_ALIASES
{'rows': 0}

df._AXIS_NUMBERS
{'columns': 1, 'index': 0}

df._AXIS_NAMES
{0: 'index', 1: 'columns'}
brtdzjyr

brtdzjyr5#

当axis ='rows'或axis=0时,意味着按行的方向从上到下访问元素。如果沿着轴=0应用sum,它将给予每列的总和。
当axis ='columns'或axis=1时,表示按列的方向(从左到右)访问元素。如果沿着axis=1应用sum,我们将得到每行的总和。
仍然令人困惑!但上面的内容让我更容易一点。

jaxagkaj

jaxagkaj6#

我记得维度的变化,如果轴=0,行改变,列不变,如果轴=1,列改变,行不变。

nnvyjq4y

nnvyjq4y7#

我认为需要找到一种方法来描述它在一个统一的方式。我认为有两个步骤来记住它:
1.记住axis = 1表示左右,axis = 0表示上下;你需要一些时间来记住它,我们帮不上忙。
1.记住,当做计算时(如np.mean,np.max),axis意味着沿着那个方向计算(所以axis = 1意味着沿着从左到右计算),而当做索引或搜索时,axis意味着你沿着那个方向搜索(所以df.drop('name',axis =1)意味着你从左到右搜索以找到'name'表示,显然它应该是一个列名而不是行索引)。

相关问题