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.
Es ist vielleicht am einfachsten, sich als 0 = down und 1 = across zu erinnern.
Das heisst:
axis=0
, um eine Methode in jeder Spalte oder auf die Zeilenbeschriftungen (den Index) anzuwenden.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.
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
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.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)
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
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'}
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.