J'ai été très confus sur la façon dont les axes python sont définis et s'ils font référence aux lignes ou aux colonnes d'un DataFrame. Considérez 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 obtiendrons une moyenne sur les lignes:
>>> df.mean(axis=1)
0 1
1 2
2 3
Cependant, si nous appelons df.drop(name, axis=1)
, nous supprimons en fait 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
Quelqu'un peut-il m'aider à comprendre ce que signifie un "axe" dans pandas / numpy / scipy?
Une note latérale, DataFrame.mean
pourrait être mal définie. Cela dit dans la documentation que DataFrame.mean
cela axis=1
est censé signifier une moyenne sur les colonnes, pas sur les lignes ...
mean
et ledrop
. Il faut une réflexion non linéaire pour arriver au comportement réel.Réponses:
Il est peut-être plus simple de s'en souvenir comme étant 0 = bas et 1 = transversal .
Ça signifie:
axis=0
pour appliquer une méthode en bas de chaque colonne ou aux étiquettes de ligne (l'index).axis=1
pour appliquer une méthode à chaque ligne ou aux étiquettes de colonne.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 du mot par NumPy
axis
. L'utilisation est expliquée dans le glossaire de NumPy :Donc, concernant la méthode dans la question
df.mean(axis=1)
,, semble être correctement définie. Il prend la moyenne des entrées horizontalement sur les colonnes , c'est-à-dire le long de chaque ligne individuelle. D'autre part,df.mean(axis=0)
serait une opération agissant verticalement vers le bas à travers les rangées .De même,
df.drop(name, axis=1)
fait référence à une action sur les étiquettes de colonne, car elles traversent intuitivement l'axe horizontal. La spécificationaxis=0
ferait plutôt agir la méthode sur les lignes.la source
df.apply
comme similaire à une méthode telle quedf.sum
. Par exemple,df.sum(axis=0)
additionne chaque colonne du DataFrame. De même, vous pouvez écriredf.apply(sum, axis=0)
pour faire exactement la même opération. Alors que l'opération est effectivement appliquée à chaque colonne dans le DataFrame, la fonction réelle descend l'axe 0.MARGIN
(similaire à celle desaxis
pandas) de "1" correspond à "lignes", ce qui signifie que la fonction est appliquée à chaque ligne , tandis que le une valeur plus élevée de «2» fait référence aux «colonnes», ce qui signifie que la fonction est appliquée à chaque colonne .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
À propos
df.drop
(l'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
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
la source
Il y a déjà des réponses correctes, mais je vous donne un autre exemple avec> 2 dimensions.
Le paramètre
axis
signifie l' axe à modifier .Par exemple, considérez qu'il existe un dataframe avec la dimension axbxc .
df.mean(axis=1)
renvoie une trame de données avec dimenstion ax 1 xc .df.drop("col4", axis=1)
renvoie une trame de données avec la dimension ax (b-1) xc .Ici,
axis=1
signifie le deuxième axe qui estb
, donc lab
valeur sera modifiée dans ces exemples.la source
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 les calculs se déroulent. Un autre alias pour «index» est «lignes» .
Quand
axis='index'
est utilisé, les calculs se déroulent dans les colonnes, ce qui est déroutant. Mais je m'en souviens comme obtenant un résultat de la même taille qu'une autre ligne.Faisons apparaître quelques 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 obtenir 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)
Ajouter une nouvelle ligne avec axis = 0 / index / rows
Utilisons ces résultats pour ajouter des lignes ou des colonnes supplémentaires pour compléter l'explication. Ainsi, chaque fois que vous utilisez axis = 0 / index / rows, c'est comme obtenir 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
Ajouter une nouvelle colonne avec axe = 1 / colonnes
De même, lorsque axis = 1 / columns, il créera des données qui peuvent être facilement converties dans 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'}
la source
Lorsque axis = 'rows' ou axis = 0, cela signifie accéder aux éléments dans le sens 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 axis = 'colonnes' ou axis = 1, cela signifie accéder 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.
Toujours déroutant! Mais ce qui précède me facilite un peu la tâche.
la source
Je trouve toutes les autres réponses déroutantes. Voici comment j'y pense:
Donc
df.drop(name, axis=1)
: supprime une colonnedf.mean(axis=1)
: calcule une colonne (le résultat peut être ajouté en tant que nouvelle colonne)la source