wake-up-neo.net

Mehrdeutigkeit bei der Definition der "Achse" von Pandas Dataframe/Numpy Array

Ich war sehr verwirrt darüber, wie Python-Achsen definiert werden und ob sie sich auf die Zeilen oder Spalten eines DataFrame beziehen. Beachten Sie den folgenden Code:

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

Wenn wir also df.mean(axis=1) aufrufen, erhalten wir einen Mittelwert in den Zeilen:

>>> df.mean(axis=1)
0    1
1    2
2    3

Wenn wir jedoch df.drop(name, axis=1) aufrufen, sind wir tatsächlich Spalte löschen, nicht eine Zeile:

>>> df.drop("col4", axis=1)
   col1  col2  col3
0     1     1     1
1     2     2     2
2     3     3     3

Kann mir jemand helfen zu verstehen, was unter "Achsen" in Pandas/Numpy/Scipy verstanden wird?

Eine Randbemerkung DataFrame.mean könnte nur falsch definiert werden. In der Dokumentation für DataFrame.mean heißt es, dass axis=1 einen Mittelwert über den Spalten und nicht die Zeilen bedeuten soll.

74
hlin117

Es ist vielleicht am einfachsten, sich als 0 = down und 1 = across zu erinnern. 

Das heisst:

  • Verwenden Sie axis=0, um eine Methode in jeder Spalte oder auf die Zeilenbeschriftungen (den Index) anzuwenden.
  • Verwenden Sie axis=1, um eine Methode in jeder Zeile oder auf die Spaltenbeschriftungen anzuwenden.

Hier ist ein Bild, das die Teile eines DataFrames zeigt, auf die sich jede Achse bezieht:

Es ist auch nützlich zu wissen, dass Pandas die Verwendung des Wortes axis von NumPy verfolgt. Die Verwendung wird in NumPys Glossar der Begriffe erläutert:

Achsen werden für Arrays mit mehr als einer Dimension definiert. Ein zweidimensionales Array hat zwei entsprechende Achsen: Die erste vertikal verlaufende abwärts über die Zeilen (Achse 0) und die zweite verlaufende horizontal über die Spalten (Achse 1). [meine Betonung

Die Methode in der Frage, df.mean(axis=1), scheint also richtig definiert zu sein. Es nimmt den Mittelwert der Einträge horizontal über Spalten, dh entlang jeder einzelnen Zeile. Auf der anderen Seite wäre df.mean(axis=0) eine vertikal wirkende Operation über Zeilen abwärts.

Ähnlich bezieht sich df.drop(name, axis=1) auf eine Aktion auf Spaltenbeschriftungen, da diese intuitiv über die horizontale Achse verlaufen. Wenn Sie axis=0 angeben, wirkt sich die Methode stattdessen auf Zeilen aus.

147
Alex Riley

Eine andere Art zu erklären:

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

Über df.drop (Achse bedeutet die Position)

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

Über df.apply (Achse bedeutet Richtung)

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

Es gibt bereits richtige Antworten, aber ich gebe Ihnen ein weiteres Beispiel mit> 2 Dimensionen. 

Der Parameter axis bedeutet Achse, die geändert werden soll.
Angenommen, es gibt einen Datenrahmen mit der Dimension a x b x c

  • df.mean(axis=1) gibt ein Datenframe mit der Dimension a x 1 x c zurück. 
  • df.drop("col4", axis=1) gibt einen Datenrahmen mit der Dimension a x (b-1) x c zurück.
5
jeongmin.cha

Es sollte allgemeiner bekannt sein, dass die String-Aliase 'index' und 'column' anstelle der ganzen Zahlen 0/1 verwendet werden können. Die Aliase sind viel expliziter und helfen mir zu erinnern, wie die Berechnungen ablaufen. Ein weiterer Alias ​​für 'Index' ist 'Zeilen' .

Wenn axis='index' verwendet wird, werden die Berechnungen in den Spalten durchgeführt, was verwirrend ist. Aber ich erinnere mich daran, als ich ein Ergebnis erhielt, das die gleiche Größe wie eine andere Reihe hat.

Lassen Sie uns einige Daten auf dem Bildschirm erhalten, um zu sehen, worüber ich spreche:

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

Wenn wir den Mittelwert aller Spalten verwenden möchten, verwenden wir axis='index', um Folgendes zu erhalten:

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

Das gleiche Ergebnis würde erhalten werden durch:

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

Um eine Operation von links nach rechts in den Zeilen zu erhalten, verwenden Sie axis = 'column'. Ich erinnere mich daran, als ich daran dachte, dass meinem DataFrame eine zusätzliche Spalte hinzugefügt werden könnte:

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

Das gleiche Ergebnis würde erhalten werden durch:

df.mean(axis=1)

Fügen Sie eine neue Zeile mit Achse = 0/Index/Zeilen hinzu

Verwenden Sie diese Ergebnisse, um zusätzliche Zeilen oder Spalten hinzuzufügen, um die Erläuterung zu vervollständigen. Immer wenn Sie axis = 0/index/rows verwenden, ist es so, als würde eine neue Zeile des DataFrame abgerufen. Fügen wir eine Zeile hinzu:

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

Fügen Sie eine neue Spalte mit Achse = 1/Spalten hinzu

In ähnlicher Weise werden bei Achsen = 1/Spalten Daten erstellt, die leicht in eine eigene Spalte umgewandelt werden können:

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

Es scheint, dass Sie alle Aliase mit den folgenden privaten Variablen sehen können:

df._AXIS_ALIASES
{'rows': 0}

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

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

Wenn axis = 'rows' oder axis = 0 ist, bedeutet dies, dass auf Elemente in Zeilenrichtung von oben nach unten zugegriffen werden kann. Wenn Sie die Summe entlang der Achse = 0 anwenden, erhalten Sie die Gesamtsummen für jede Spalte.

Wenn axis = 'columns' oder axis = 1, bedeutet dies, dass auf Elemente in Richtung der Spalten von links nach rechts zugegriffen werden kann. Wenn Sie die Summe entlang der Achse = 1 anwenden, erhalten Sie die Summen jeder Zeile.

Immer noch verwirrend! Aber das Obige macht es mir ein bisschen leichter.

0
newbie