web-dev-qa-db-ja.com

Pandas Dataframe / Numpy Array "axis"定義のあいまいさ

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の「軸」の意味を理解するのを手伝ってくれますか?

サイドノート_DataFrame.mean_は間違って定義されている可能性があります。 _DataFrame.mean_ のドキュメントでは、_axis=1_は行ではなく列の平均を意味することになっていると...

81
hlin117

0 = downおよび1 = acrossのように覚えておくのがおそらく最も簡単でしょう。

これの意味は:

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

以下は、各軸が参照するDataFrameの部分を示す図です。

Pandas=がNumPyのWord axisの使用に続くことを覚えておくと便利です。使用方法はNumPyの 用語集 で説明されています。

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

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

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

153
Alex Riley

説明する別の方法:

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

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

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

  • df.mean(axis=1)は、次元a x 1 x cのデータフレームを返します。
  • df.drop("col4", axis=1)は、次元a x(b-1)x cのデータフレームを返します。
5
jeongmin.cha

文字列エイリアス'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'}
1
Ted Petrou

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

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

まだわかりにくい!しかし、上記のおかげで少し簡単になりました。

0
newbie