web-dev-qa-db-fra.com

Ambiguïté dans la définition "axe" de Pandas Dataframe/Numpy Array

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

74
hlin117

C'est peut-être plus simple de s'en souvenir en tant que 0 = bas et 1 = transversal

Ça signifie:

  • Utilisez axis=0 pour appliquer une méthode au bas de chaque colonne ou aux étiquettes de ligne (l’index).
  • Utilisez 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.

147
Alex Riley

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

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.
5
jeongmin.cha

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)

Ajouter une nouvelle ligne avec axis = 0/index/rows

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

Ajouter une nouvelle colonne avec axe = 1/colonnes

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'}
0
Ted Petrou

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.

0
newbie