J'ai été très confus quant à la définition des axes python et à leur lien avec les lignes ou les colonnes d'un DataFrame. Considérons le code ci-dessous:
>>> 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
Donc, si nous appelons df.mean(axis=1)
, nous aurons une moyenne sur toutes les lignes:
>>> df.mean(axis=1)
0 1
1 2
2 3
Cependant, si nous appelons df.drop(name, axis=1)
, nous allons en fait supprimer une colonne, pas une ligne:
>>> df.drop("col4", axis=1)
col1 col2 col3
0 1 1 1
1 2 2 2
2 3 3 3
Est-ce que quelqu'un peut m'aider à comprendre ce que l'on entend par "axe" dans pandas/numpy/scipy?
Une note latérale, DataFrame.mean
pourrait bien être mal définie. Il est dit dans la documentation pour DataFrame.mean
que axis=1
est censé signifier une moyenne sur les colonnes, pas les lignes ...
C'est peut-être plus simple de s'en souvenir en tant que 0 = bas et 1 = transversal.
Ça signifie:
axis=0
pour appliquer une méthode au bas de chaque colonne ou aux étiquettes de ligne (l’index).axis=1
pour appliquer une méthode sur chaque ligne ou sur les libellés des colonnes.Voici une image pour montrer les parties d'un DataFrame auxquelles chaque axe fait référence:
Il est également utile de se rappeler que Pandas suit l'utilisation de Word axis
par NumPy. L'utilisation est expliquée dans NumPy's glossaire de termes :
Les axes sont définis pour les tableaux de plusieurs dimensions. Un tableau à deux dimensions a deux axes correspondants: le premier vertical vers le bas sur les lignes (axe 0) et le second horizontalement sur les colonnes (axe 1). [mon emphase]
Donc, concernant la méthode dans la question, df.mean(axis=1)
, semble être correctement défini. Il prend la moyenne des entrées horizontalement sur les colonnes, c'est-à-dire le long de chaque ligne. df.mean(axis=0)
serait en revanche une opération à la verticale vers le bas sur les lignes.
De même, df.drop(name, axis=1)
fait référence à une action sur les étiquettes de colonne, car elles passent intuitivement sur l’axe horizontal. Si vous spécifiez axis=0
, la méthode agira à la place sur les lignes.
Une autre façon d'expliquer:
// 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
A propos de df.drop
(axe signifie la 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
À propos de df.apply
(axe signifie direction)
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
Il y a déjà de bonnes réponses, mais je vous donne un autre exemple avec> 2 dimensions.
Le paramètre axis
signifie axe à modifier.
Par exemple, considérons qu'il existe un cadre de données de dimension a x b x c
df.mean(axis=1)
renvoie une trame de données de dimension a x 1 x c. df.drop("col4", axis=1)
renvoie un cadre de données de dimension a x (b-1) x c.Il devrait être plus largement connu que les alias de chaîne 'index' et 'colonnes' peuvent être utilisés à la place des entiers 0/1. Les alias sont beaucoup plus explicites et m'aident à me rappeler comment se déroulent les calculs. Un autre alias pour 'index' est 'rows' .
Lorsque axis='index'
est utilisé, les calculs sont effectués en bas des colonnes, ce qui prête à confusion. Mais je me souviens que cela donne un résultat de la même taille qu’une autre rangée.
Ayons des données à l'écran pour voir de quoi je parle:
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
Lorsque nous voulons prendre la moyenne de toutes les colonnes, nous utilisons axis='index'
pour obtenir ce qui suit:
df.mean(axis='index')
a 0.562664
b 0.478956
c 0.410046
d 0.546366
dtype: float64
Le même résultat serait obtenu par:
df.mean() # default is axis=0
df.mean(axis=0)
df.mean(axis='rows')
Pour utiliser une opération de gauche à droite sur les lignes, utilisez axis = 'columns'. Je m'en souviens en pensant qu'une colonne supplémentaire peut être ajoutée à mon 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
Le même résultat serait obtenu par:
df.mean(axis=1)
Utilisons ces résultats pour ajouter des lignes ou des colonnes supplémentaires afin de compléter l'explication. Ainsi, chaque fois que vous utilisez axis = 0/index/rows, vous obtenez une nouvelle ligne du DataFrame. Ajoutons une ligne:
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
De même, lorsque axe = 1/colonnes, cela créera des données qui peuvent facilement être transformées en sa propre colonne:
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
Il semble que vous puissiez voir tous les alias avec les variables privées suivantes:
df._AXIS_ALIASES
{'rows': 0}
df._AXIS_NUMBERS
{'columns': 1, 'index': 0}
df._AXIS_NAMES
{0: 'index', 1: 'columns'}
Lorsque axe = 'lignes' ou axe = 0, cela signifie que vous accédez aux éléments dans la direction des lignes, de haut en bas. Si vous appliquez la somme le long de l'axe = 0, cela nous donnera les totaux de chaque colonne.
Lorsque axe = 'colonnes' ou axe = 1, cela signifie que vous accédez aux éléments dans le sens des colonnes, de gauche à droite. Si vous appliquez la somme le long de l'axe = 1, nous obtiendrons les totaux de chaque ligne.
Encore déroutant! Mais ce qui précède me facilite un peu la tâche.