Pandasデータフレーム/ Numpy配列の「軸」定義のあいまいさ


91

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

誰かがパンダ/ numpy / scipyの「軸」が何を意味するのか理解するのを手伝ってもらえますか?

補足として、DataFrame.mean間違って定義されている可能性があります。それはのための文書で述べているDataFrame.meanことaxis=1の列ではなく行にわたる平均を意味することになっています...


エイリアス、「列」および「インデックス」/「行」の 詳細な説明については、以下のこの回答を参照してください
Ted Petrou 2017年

これは奇妙なことです。軸はとの間で一貫している必要がmeanありdropます。実際の行動にたどり着くには、非線形の思考が必要です。
javadba 2018

回答:


167

0 =ダウンおよび1 =アクロスとして覚えておくのがおそらく最も簡単です。

これの意味は:

  • axis=0各列の下、または行ラベル(インデックス)にメソッドを適用するために使用します。
  • axis=1各行または列ラベルにメソッドを適用するために使用します。

これは、各軸が参照するDataFrameの部分を示す画像です。

PandasはNumPyによる単語の使用に従っていることを覚えておくことも役立ちますaxis。使用法は、NumPyの用語集で説明されています

軸は、複数の次元を持つ配列に対して定義されます。2次元配列には、対応する2つの軸があります。1つ目は行を横切って垂直に下向きに走り(軸0)、2つ目は列を横切っ水平に走ります(軸1)。[私の強調]

したがって、質問のメソッドに関しては、df.mean(axis=1)が正しく定義されているようです。これは、列全体で水平方向に、つまり個々の行に沿ってエントリの平均を取ります。一方、行を横切ってdf.mean(axis=0)垂直下向きに動作する操作になります

同様に、df.drop(name, axis=1)列ラベルは水平軸を直観的に横切るため、列ラベルに対するアクションを指します。指定axis=0すると、代わりにメソッドが行に作用します。


3
私が苦労したのは、df.apply(...、axis = 0)が、軸0(インデックス)を「実行」せず、列を実行して、すべてのインデックスを含むSeriesを取得したことです。手がかりは、df.apply(...、axis = 0)がSeriesを返すため、完全なインデックスに対して実行されている操作を適用できることです。
moritzschaefer 2016年

2
df.applyような方法と同じように見れば、それも役立つと思いますdf.sum。たとえばdf.sum(axis=0)、DataFrameの各列を合計します。同様に、df.apply(sum, axis=0)まったく同じ操作を実行するように書くことができます。動作は、実際、データフレーム内の各列に軸0ダウン実際の機能が実行印加される
アレックス・ライリー

残念ながら、命名規則と順序の規則がRの適用関数反対です。Rでは、「1」の低い方の値(パンダの場合と同様)は「行」に対応します。これは、関数が各行に適用されることを意味します。「2」の値が大きいほど「列」を指し、関数が各列に適用されることを意味しますMARGINaxis
キースヒューイット

それはパンダの破壊的なバグです
微積分

10

説明する別の方法:

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

軸1と軸0に平行なのは同じ意味だと思いませんか?
ニュアンス2017

9

すでに適切な答えがありますが、2次元を超える別の例を示します。

パラメータaxis、変更する軸を意味します
たとえば、次元axbxcのデータフレームがあるとします。

  • df.mean(axis=1)dimenstionでデータフレームを返す斧1 XC
  • df.drop("col4", axis=1)次元ax(b-1)xcのデータフレームを返します。

ここで、axis=1は2番目の軸であるを意味するbためb、これらの例では値が変更されます。


1
この答えは、このトピックで見たどの視覚化よりも直感的です。ただし、xarrayは、パンダよりも多次元配列に適しています。
alys 2018年

2

文字列エイリアス「index」「columns」を整数0/1の代わりに使用できることはもっと広く知られているはずです。エイリアスははるかに明確であり、計算がどのように行われるかを思い出すのに役立ちます。'index'のもう1つのエイリアスは'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'}

1

axis = 'rows'またはaxis = 0の場合、行の方向から下へのアクセス要素を意味します。axis = 0に沿って合計を適用すると、各列の合計が得られます。

axis = 'columns'またはaxis = 1の場合、左から右へ、列の方向に要素にアクセスすることを意味します。axis = 1に沿って合計を適用すると、各行の合計が得られます。

まだ紛らわしい!しかし、上記は私にとってそれを少し簡単にします。


0

他のすべての答えは紛らわしいと思います。これが私がそれについてどう思うかです:

axis=0:結果の形状が水平(行)
axis=1:結果の形状が垂直(列)

そう

  • df.drop(name, axis=1):列を削除します
  • df.mean(axis=1):列を計算します(結果は新しい列として追加できます)
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.