Voici mon code pour générer un dataframe:
import pandas as pd
import numpy as np
dff = pd.DataFrame(np.random.randn(1,2),columns=list('AB'))
alors j'ai eu le dataframe:
+------------+---------+--------+
| | A | B |
+------------+---------+---------
| 0 | 0.626386| 1.52325|
+------------+---------+--------+
Quand je tape la commande:
dff.mean(axis=1)
J'ai eu :
0 1.074821
dtype: float64
Selon la référence des pandas, axe = 1 représente les colonnes et j’espère que le résultat de la commande sera
A 0.626386
B 1.523255
dtype: float64
Voici donc ma question: que veut dire axe dans les pandas?
Il spécifie l'axe le long duquel les moyennes sont calculées. Par défaut axis=0
. Cela correspond à l'utilisation de numpy.mean
lorsque axis
est spécifié explicitement (dans numpy.mean
, axis == None par défaut, qui calcule la valeur moyenne sur le tableau aplati), dans lequel axis=0
le long du rows , index dans les pandas) et axis=1
le long des columns. Pour plus de clarté, on peut choisir de spécifier axis='index'
(au lieu de axis=0
) ou axis='columns'
(au lieu de axis=1
).
+------------+---------+--------+
| | A | B |
+------------+---------+---------
| 0 | 0.626386| 1.52325|----axis=1----->
+------------+---------+--------+
| |
| axis=0 |
↓ ↓
Ces réponses aident à expliquer cela, mais cela n’est pas encore parfaitement intuitif pour un non-programmeur (c’est-à-dire quelqu'un comme moi qui apprend Python pour la première fois dans le contexte d’un cours de science des données). Je trouve toujours que l’utilisation des termes "le long" ou "pour chaque" par rapport aux lignes et aux colonnes est source de confusion.
Ce qui a plus de sens pour moi est de le dire ainsi:
Ainsi, une moyenne sur l'axe 0 sera la moyenne de toutes les lignes de chaque colonne et une moyenne sur l'axe 1 sera une moyenne de toutes les colonnes de chaque ligne.
En fin de compte, c'est dire la même chose que @zhangxaochen et @Michael, mais d'une manière qui est plus facile à assimiler pour moi.
axis
fait référence à la dimension du tableau, dans le cas de pd.DataFrame
s axis=0
est la dimension qui pointe vers le bas et axis=1
celle qui pointe à droite.
Exemple: Pensez à une ndarray
de forme (3,5,7)
.
a = np.ones((3,5,7))
a
est une ndarray
en 3 dimensions, c’est-à-dire qu’elle a 3 axes ("axes" est la pluralité de "axe"). La configuration de a
ressemblera à 3 tranches de pain, chaque tranche étant de dimension 5 sur 7. a[0,:,:]
fera référence à la 0ème tranche, a[1,:,:]
fera référence à la 1ère tranche, etc.
a.sum(axis=0)
appliquera sum()
le long du 0-ème axe de a
. Vous ajouterez toutes les tranches et vous obtiendrez une tranche de forme (5,7)
.
a.sum(axis=0)
est équivalent à
b = np.zeros((5,7))
for i in range(5):
for j in range(7):
b[i,j] += a[:,i,j].sum()
b
et a.sum(axis=0)
ressembleront tous les deux à ceci
array([[ 3., 3., 3., 3., 3., 3., 3.],
[ 3., 3., 3., 3., 3., 3., 3.],
[ 3., 3., 3., 3., 3., 3., 3.],
[ 3., 3., 3., 3., 3., 3., 3.],
[ 3., 3., 3., 3., 3., 3., 3.]])
Dans un pd.DataFrame
, les axes fonctionnent de la même manière que dans numpy.array
s: axis=0
appliquera sum()
ou toute autre fonction de réduction pour chaque colonne.
N.B. Dans la réponse de @ zhangxaochen, je trouve les expressions "le long des lignes" et "le long des colonnes" légèrement déroutantes. axis=0
doit faire référence à "le long de chaque colonne", et axis=1
"le long de chaque ligne".
Le moyen le plus simple pour moi de comprendre est de déterminer si vous calculez une statistique pour chaque colonne (axis = 0
) ou chaque ligne (axis = 1
). Si vous calculez une statistique, disons une moyenne, avec axis = 0
, vous obtiendrez cette statistique pour chaque colonne. Donc, si chaque observation est une ligne et que chaque variable est dans une colonne, vous obtiendrez la moyenne de chaque variable. Si vous définissez axis = 1
, vous calculerez votre statistique pour chaque ligne. Dans notre exemple, vous obtiendrez la moyenne de chaque observation pour toutes vos variables (peut-être souhaitez-vous obtenir la moyenne des mesures associées).
axis = 0
: par colonne = colonne-sage = le long des lignes
axis = 1
: par rangée = rangée-rangée = le long des colonnes
Laissons visualiser (je me souviendrai toujours),
En pandas:
Supposons que, pour effectuer l'opération concat () sur dataframe1 & dataframe2, .__ nous prenions dataframe1 et prenions la 1ère ligne de dataframe1 et la placions dans le nouveau fichier DF, puis nous prenions une autre ligne de dataframe1 et les intégrions dans un nouveau fichier DF ce processus jusqu'à ce que nous atteignions le bas de dataframe1. Ensuite, nous faisons le même processus pour dataframe2.
Fondamentalement, empiler dataframe2 sur dataframe1 ou vice versa.
E.g faire une pile de livres sur une table ou un sol
Supposons que, pour effectuer l'opération concat () sur dataframe1 & dataframe2, .__, nous sortions la 1ère colonne complete (aussi appelée 1ère série) de dataframe1 et les placions dans un nouveau fichier DF, puis nous sortions la deuxième colonne de dataframe1. et maintenez-le adjacent (latéralement), nous devons répéter cette opération jusqu'à ce que toutes les colonnes soient terminées. Ensuite, nous répétons le même processus sur dataframe2 . Fondamentalement, stacking dataframe2 latéralement.
E.g organiser des livres sur une étagère.
Wes McKinney, le concepteur de pandas, travaillait beaucoup sur les données financières. Pensez aux colonnes en tant que noms d’actions et à l’index en tant que prix quotidiens. Vous pouvez alors deviner quel est le comportement par défaut (c.-à-d. axis=0
) à l’égard de ces données financières. axis=1
peut être simplement considéré comme "l'autre sens".
Par exemple, les fonctions de statistiques, telles que mean()
, sum()
, describe()
, count()
, passent toutes par colonne, car il est plus logique de les exécuter pour chaque stock. sort_index(by=)
utilise également par défaut la colonne. fillna(method='ffill')
remplira le long de la colonne car il s'agit du même stock. La valeur par défaut de dropna()
est row, car vous souhaitez probablement simplement supprimer le prix ce jour-là au lieu de supprimer tous les prix de ce stock.
De même, l'indexation entre crochets fait référence aux colonnes car il est plus courant de choisir un stock au lieu d'un jour.
L'axe en vue de la programmation est la position dans la forme Tuple. Voici un exemple:
import numpy as np
a=np.arange(120).reshape(2,3,4,5)
a.shape
Out[3]: (2, 3, 4, 5)
np.sum(a,axis=0).shape
Out[4]: (3, 4, 5)
np.sum(a,axis=1).shape
Out[5]: (2, 4, 5)
np.sum(a,axis=2).shape
Out[6]: (2, 3, 5)
np.sum(a,axis=3).shape
Out[7]: (2, 3, 4)
La moyenne sur l'axe entraînera la suppression de cette dimension.
En référence à la question initiale, la forme dff est (1,2). Utiliser axe = 1 changera la forme en (1,).
Ceci est basé sur la réponse de @ Safak . Le meilleur moyen de comprendre les axes de pandas/numpy est de créer un tableau 3D et de vérifier le résultat de la fonction sum le long des 3 axes différents.
a = np.ones((3,5,7))
a sera:
array([[[1., 1., 1., 1., 1., 1., 1.],
[1., 1., 1., 1., 1., 1., 1.],
[1., 1., 1., 1., 1., 1., 1.],
[1., 1., 1., 1., 1., 1., 1.],
[1., 1., 1., 1., 1., 1., 1.]],
[[1., 1., 1., 1., 1., 1., 1.],
[1., 1., 1., 1., 1., 1., 1.],
[1., 1., 1., 1., 1., 1., 1.],
[1., 1., 1., 1., 1., 1., 1.],
[1., 1., 1., 1., 1., 1., 1.]],
[[1., 1., 1., 1., 1., 1., 1.],
[1., 1., 1., 1., 1., 1., 1.],
[1., 1., 1., 1., 1., 1., 1.],
[1., 1., 1., 1., 1., 1., 1.],
[1., 1., 1., 1., 1., 1., 1.]]])
Regardez maintenant la somme des éléments du tableau le long de chacun des axes:
x0 = np.sum(a,axis=0)
x1 = np.sum(a,axis=1)
x2 = np.sum(a,axis=2)
vous donnera les résultats suivants:
x0 :
array([[3., 3., 3., 3., 3., 3., 3.],
[3., 3., 3., 3., 3., 3., 3.],
[3., 3., 3., 3., 3., 3., 3.],
[3., 3., 3., 3., 3., 3., 3.],
[3., 3., 3., 3., 3., 3., 3.]])
x1 :
array([[5., 5., 5., 5., 5., 5., 5.],
[5., 5., 5., 5., 5., 5., 5.],
[5., 5., 5., 5., 5., 5., 5.]])
x2 :
array([[7., 7., 7., 7., 7.],
[7., 7., 7., 7., 7.],
[7., 7., 7., 7., 7.]])
axe = 0 signifie haut en bas axe = 1 signifie gauche à droite
sums[key] = lang_sets[key].iloc[:,1:].sum(axis=0)
L’exemple donné prend la somme de toutes les données de la colonne == clé.
Regardons la table de Wiki. Ceci est une estimation du PIB par le FMI de 2010 à 2019 pour les dix premiers pays .
1. L'axe 1 agira pour chaque ligne de toutes les colonnes
Si vous voulez calculer le PIB moyen (moyen) de CHAQUE pays au cours de la décennie (2010-2019), vous devez effectuer df.mean(axis=1)
. Par exemple, si vous souhaitez calculer le PIB moyen des États-Unis de 2010 à 2019, df.loc['United States','2010':'2019'].mean(axis=1)
2. L'axe 0 agira pour chaque colonne sur toutes les lignes
Si je veux calculer le PIB moyen (moyen) pour CHAQUE année pour tous les pays, vous devez procéder à df.mean(axis=0)
. Par exemple, si vous souhaitez calculer le PIB moyen de l'année 2015 pour les États-Unis, la Chine, le Japon, l'Allemagne et l'Inde, df.loc['United States':'India','2015'].mean(axis=0)
Remarque: Le code ci-dessus fonctionnera uniquement après avoir défini la colonne "Pays (ou territoire dépendant)" comme index, à l'aide de la méthode set_index
.
Je comprends de cette façon:
Dites si votre opération nécessite une traversée de de gauche à droite/de droite à gauche dans un cadre de données, vous fusionnez apparemment des colonnes, c.-à-d. vous travaillez sur différentes colonnes . Ceci est axis = 1
Exemple
df = pd.DataFrame(np.arange(12).reshape(3,4),columns=['A', 'B', 'C', 'D'])
print(df)
A B C D
0 0 1 2 3
1 4 5 6 7
2 8 9 10 11
df.mean(axis=1)
0 1.5
1 5.5
2 9.5
dtype: float64
df.drop(['A','B'],axis=1,inplace=True)
C D
0 2 3
1 6 7
2 10 11
Le point à noter ici est que nous opérons sur des colonnes
De même, si votre opération nécessite un déplacement de de haut en bas/de bas en haut dans un cadre de données, vous fusionnez des lignes. C'est axe = 0 .
l’un des moyens simples de mémoriser l’axe 1 (colonnes), et l’axe 0 (lignes) correspond au résultat attendu. si vous attendez une sortie pour chaque ligne, vous utilisez axis = 'colonnes', par contre si vous souhaitez une sortie pour chaque colonne, vous utilisez axis = 'rows'.
Ma pensée: Axis = n, où n = 0, 1, etc. signifie que la matrice est repliée (repliée) le long de cet axe. Ainsi, dans une matrice 2D, lorsque vous réduisez le long de 0 (lignes), vous travaillez réellement sur une colonne à la fois. De même pour les matrices d'ordre supérieur.
Ce n'est pas la même chose que la référence normale à une dimension dans une matrice, où 0 -> ligne et 1 -> colonne. De même pour les autres dimensions d'un tableau de N dimensions.
Je pense qu'il y a une autre façon de le comprendre.
Pour un np.array, si nous voulons éliminer les colonnes, nous utilisons axis = 1; si nous voulons éliminer les lignes, nous utilisons axis = 0.
np.mean(np.array(np.ones(shape=(3,5,10))),axis = 0).shape # (5,10)
np.mean(np.array(np.ones(shape=(3,5,10))),axis = 1).shape # (3,10)
np.mean(np.array(np.ones(shape=(3,5,10))),axis = (0,1)).shape # (10,)
Pour les objets pandas, axis = 0
correspond à une opération par ligne et axis = 1
à une opération par colonne. Ceci est différent de numpy
par définition, nous pouvons vérifier les définitions de numpy.doc et pandas.doc
Je suis un débutant aux pandas. Mais c’est ainsi que je comprends l’axe des pandas:
Axe Constante Variante Direction
0 colonne rangée vers le bas |
1 rangée de colonne vers la droite ->
Donc, pour calculer la moyenne d'une colonne, cette colonne doit être constante mais les lignes en dessous peuvent changer (varier) donc c'est axe = 0.
De même, pour calculer la moyenne d'une ligne, cette ligne particulière est constante mais elle peut parcourir différentes colonnes (variable) , axe = 1.