Pandas Dataframe/Numpy Array"轴"定义中的歧义

hli*_*117 81 python arrays numpy dataframe pandas

关于如何定义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
Run Code Online (Sandbox Code Playgroud)

因此,如果我们打电话df.mean(axis=1),我们将获得跨行的平均值:

>>> df.mean(axis=1)
0    1
1    2
2    3
Run Code Online (Sandbox Code Playgroud)

但是,如果我们调用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
Run Code Online (Sandbox Code Playgroud)

有人能帮助我理解pandas/numpy/scipy中"轴"的含义吗?

旁注,DataFrame.mean可能被定义错了.它在文档中说,DataFrame.meanaxis=1应该是指列的平均值,而不是行...

Ale*_*ley 153

记住它可能最简单,因为0 =向下,1 =跨越.

这意味着:

  • 使用axis=0的方法应用于沿着每列,或行标签(索引).
  • 用于axis=1跨每行或列标签应用方法.

这是一张图片,显示每个轴引用的DataFrame部分:

记住Pandas跟随NumPy使用这个词也是有用的axis.用法在NumPy的术语表中解释:

轴是为具有多个维度的数组定义的.二维阵列具有两个相应的轴:第一个在行(轴0)上垂直向下运行,第二个轴在列(轴1)水平运行.[ 我的重点 ]

因此,关于问题中的方法df.mean(axis=1),似乎是正确定义的.它在列之间水平地采用条目的平均值,即沿着每个单独的行.另一方面,df.mean(axis=0)将是跨行垂直向下作用的操作.

类似地,df.drop(name, axis=1)指的是列标签上的动作,因为它们直观地穿过水平轴.指定axis=0会使方法代替行.

  • 使我感到挣扎的是,df.apply(...,axis = 0)并未“超出”轴0(索引),而是在列上运行,重现了包含所有索引的Series。提示是df.apply(...,axis = 0)返回Series,因此您可以对整个索引应用运行操作。 (2认同)
  • 我认为,如果您将 `df.apply` 视为类似于诸如 `df.sum` 的方法,它也会有所帮助。例如,`df.sum(axis=0)` 对 DataFrame 的每一列求和。类似地,您可以编写`df.apply(sum, axis=0)` 来执行完全相同的操作。虽然该操作确实应用于 DataFrame 中的每一列,但实际的函数沿着轴 0 运行。 (2认同)

o0o*_*o0o 9

另一种解释方式:

// 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
Run Code Online (Sandbox Code Playgroud)

关于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
Run Code Online (Sandbox Code Playgroud)

关于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
Run Code Online (Sandbox Code Playgroud)


jeo*_*cha 6

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

参数axis表示要更改的轴.
例如,考虑存在具有维度axbxc的数据帧.

  • df.mean(axis=1)返回尺寸为1 xc的数据帧.
  • df.drop("col4", axis=1)返回维度为ax(b-1)xc的数据帧.

  • 这个答案对我来说比我在这个主题上看到的任何可视化都更直观。然而,对于多维数组,xarray 比 pandas 更好。 (2认同)

Ted*_*rou 5

应该更广泛地知道,字符串别名“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
Run Code Online (Sandbox Code Playgroud)

当我们想要取所有列的平均值时,我们可以axis='index'使用以下方法:

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

通过以下方式可以获得相同的结果:

df.mean() # default is axis=0
df.mean(axis=0)
df.mean(axis='rows')
Run Code Online (Sandbox Code Playgroud)

要在行上使用从左到右的操作,请使用 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
Run Code Online (Sandbox Code Playgroud)

通过以下方式可以获得相同的结果:

df.mean(axis=1)
Run Code Online (Sandbox Code Playgroud)

添加 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
Run Code Online (Sandbox Code Playgroud)

添加 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
Run Code Online (Sandbox Code Playgroud)

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

df._AXIS_ALIASES
{'rows': 0}

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

df._AXIS_NAMES
{0: 'index', 1: 'columns'}
Run Code Online (Sandbox Code Playgroud)