Cliquez ici pour plus de détails ↓ https://pandas.pydata.org/pandas-docs/stable/user_guide/advanced.html Selon le document, il s'agit d'un index hiérarchique et peut être utilisé lors de la manipulation de données de grande dimension (en gros).
Le panneau qui gère la structure de données 3D dans les pandas a été aboli, alors vérifiez comment le gérer ici. Puisqu'il s'agit d'un mémorandum personnel, il n'est pas du tout exhaustif. Par conséquent, si vous avez des questions, vous devez enquêter le cas échéant.
python 3.7.7 pandas 1.1.1 Environnement d'exécution: notebook jupyter
Comme prévu, les données de recherche ne peuvent pas être utilisées, donc des échantillons de données seront créés de manière appropriée.
#importation de pandas
import pandas as pd
#Création de données
array =[['cat','cat','cat','cat','cat','dog','dog','dog','bird','bird'],
['black','white','white','brown','brown','black','white','brown','white','yellow'],
['male','male','female','male','female','female','female','male','male','female'],
[3,5,5,5,4,7,8,10,1,2],
[20,25,26,30,22,77,55,90,10,15],
[3.6,4.5,4.0,5.2,3.0,15.6,10.5,20.1,0.52,0.89]]
#Convertir en DataFrame.Inversion des lignes et des colonnes avec T
df = pd.DataFrame(array).T
#paramètres de colonne
df.columns = ['animal','color','male or female','age','height','weight']
Comme ça. Puisque le contenu est créé implicitement, il semble y avoir un chat très obèse.
animal | color | male or female | age | height | weight | |
---|---|---|---|---|---|---|
0 | cat | black | male | 3 | 20 | 3.6 |
1 | cat | white | male | 5 | 25 | 4.5 |
2 | cat | white | female | 5 | 26 | 4 |
3 | cat | brown | male | 5 | 30 | 5.2 |
4 | cat | brown | female | 4 | 22 | 3 |
5 | dog | black | female | 7 | 77 | 15.6 |
6 | dog | white | female | 8 | 55 | 10.5 |
7 | dog | brown | male | 10 | 90 | 20.1 |
8 | bird | white | male | 1 | 10 | 0.52 |
9 | bird | yellow | female | 2 | 15 | 0.89 |
A part: Vous pouvez utiliser .to_markdown () pour créer une table de notation markdown. Il semble qu'il a été implémenté à partir de la version 1.0.0 ou ultérieure des pandas? Cependant, au final, .to_html () est redevable.
index Comment définir et réinitialiser l'index
Le nom de colonne spécifié par set_index est l'indice du niveau à partir de 0 à partir de animal. level→0 : animal, 1 : color, 2 : male or female
df2 = df.set_index(['animal','color','male or female'])
age | height | weight | |||
---|---|---|---|---|---|
animal | color | male or female | |||
cat | black | male | 3 | 20 | 3.6 |
white | male | 5 | 25 | 4.5 | |
female | 5 | 26 | 4 | ||
brown | male | 5 | 30 | 5.2 | |
female | 4 | 22 | 3 | ||
dog | black | female | 7 | 77 | 15.6 |
white | female | 8 | 55 | 10.5 | |
brown | male | 10 | 90 | 20.1 | |
bird | white | male | 1 | 10 | 0.52 |
yellow | female | 2 | 15 | 0.89 |
En passant, les niveaux d'index peuvent être définis dans l'ordre de votre choix.
df3 = df.set_index(['animal','male or female','color'])
age | height | weight | |||
---|---|---|---|---|---|
animal | male or female | color | |||
cat | male | black | 3 | 20 | 3.6 |
white | 5 | 25 | 4.5 | ||
female | white | 5 | 26 | 4 | |
male | brown | 5 | 30 | 5.2 | |
female | brown | 4 | 22 | 3 | |
dog | female | black | 7 | 77 | 15.6 |
white | 8 | 55 | 10.5 | ||
male | brown | 10 | 90 | 20.1 | |
bird | male | white | 1 | 10 | 0.52 |
female | yellow | 2 | 15 | 0.89 |
En comparant avec le tableau ci-dessus, on peut confirmer que les valeurs des premier et second niveaux sont interchangées.
En remarque, .set_index () a drop comme paramètre, qui est True par défaut. Ceci spécifie s'il faut supprimer les données de la colonne utilisée comme index. Par conséquent, lorsque drop = False, les données de la colonne spécifiée dans Index restent telles quelles, comme indiqué ci-dessous.
df4 = df.set_index(['animal','color','male or female'], drop=False)
animal | color | male or female | age | height | weight | |||
---|---|---|---|---|---|---|---|---|
animal | color | male or female | ||||||
cat | black | male | cat | black | male | 3 | 20 | 3.6 |
white | male | cat | white | male | 5 | 25 | 4.5 | |
female | cat | white | female | 5 | 26 | 4 | ||
brown | male | cat | brown | male | 5 | 30 | 5.2 | |
female | cat | brown | female | 4 | 22 | 3 | ||
dog | black | female | dog | black | female | 7 | 77 | 15.6 |
white | female | dog | white | female | 8 | 55 | 10.5 | |
brown | male | dog | brown | male | 10 | 90 | 20.1 | |
bird | white | male | bird | white | male | 1 | 10 | 0.52 |
yellow | female | bird | yellow | female | 2 | 15 | 0.89 |
Comme ça. Fondamentalement, il semble qu'il n'y ait aucun problème avec la valeur par défaut, vous n'avez donc pas à vous en soucier.
Pour réinitialiser l'index, utilisez .reset_index ().
df1 = df2.reset_index()
Si vous comparez df et df1, vous pouvez voir que le tableau est le même.
Confirmation que le nom de colonne spécifié dans Index est susceptible d'être inclus dans les noms.
df2.index
>
MultiIndex([( 'cat', 'black', 'male'),
( 'cat', 'white', 'male'),
( 'cat', 'white', 'female'),
( 'cat', 'brown', 'male'),
( 'cat', 'brown', 'female'),
( 'dog', 'black', 'female'),
( 'dog', 'white', 'female'),
( 'dog', 'brown', 'male'),
('bird', 'white', 'male'),
('bird', 'yellow', 'female')],
names=['animal', 'color', 'male or female'])
Je me demande s'il peut être utilisé lors de la vérification du nom de la colonne dans Index.
df2.index.names
>
FrozenList(['animal', 'color', 'male or female'])
De là, nous utiliserons df2 pour voir diverses choses.
Utilisez .index.get_level_values (). Cela renverra une étiquette d'un niveau spécifique en tant que vecteur.
#Spécifié par un nom de colonne de niveau spécifique
df2.index.get_level_values('animal')
> Index(['cat', 'cat', 'cat', 'cat', 'cat', 'dog', 'dog', 'dog', 'bird', 'bird'], dtype='object', name='animal')
Même résultat que ci-dessus ↓
#Peut également être spécifié par numéro de niveau
df2.index.get_level_values(0)
> Index(['cat', 'cat', 'cat', 'cat', 'cat', 'dog', 'dog', 'dog', 'bird', 'bird'], dtype='object', name='animal')
Évitez la duplication avec set, convertissez en liste et triez-la pour créer une nouvelle liste. Si vous souhaitez utiliser l'ordre décroissant, définissez l'argument reverse sur True. (Je ne pense pas que cela ait beaucoup de sens ici.)
#Obtenez une étiquette sans duplication
a = sorted(list(set(df2.index.get_level_values('animal'))))
a
> ['bird', 'cat', 'dog']
En utilisant .xs (), vous pouvez spécifier le nom de la colonne d'index et sa valeur (étiquette) pour la sélection ou l'extraction.
Utilisons la liste créée précédemment pour vérifier le fonctionnement de xs (). Le contenu est ['oiseau', 'chat', 'chien'] ← En utilisant les valeurs de cette liste comme clés, trouvez la taille moyenne de chaque animal mâle et femelle.
M = {}
F = {}
for s in a:
m = df2['height'].xs([s, 'male'], level=['animal', 'male or female']).mean()
M[s] = m
f = df2['height'].xs([s, 'female'], level=['animal', 'male or female']).mean()
F[s] = f
#résultat
M
> {'bird': 10.0, 'cat': 25.0, 'dog': 90.0}
F
> {'bird': 15.0, 'cat': 24.0, 'dog': 66.0}
En plus de .mean (), .min (), .max (), .std (), .count (), etc. peuvent être utilisés selon le but.
Pour le moment, commentaire
Tout d'abord, spécifiez le nom de la colonne de la valeur que vous voulez trouver (cette fois, je veux connaître la moyenne de 'hauteur') df2['height']
Ensuite, utilisez .xs () pour définir des spécifications détaillées. df2['height'].xs([s, 'male'], level=['animal', 'male or female'])
Premièrement, à propos de [s, 'male']. Cette fois, afin de calculer la taille moyenne de chaque mâle (mâle) et femelle (femelle) de chaque animal, spécifiez une étiquette correspondant à l'information "quel animal et quel sexe" dans le premier argument de .xs ().
Ensuite, à propos de level = ['animal', 'male or female']. Cela semble indiquer le niveau du [s, 'mâle'] spécifié précédemment. Donc, ce serait bien si vous pouviez correspondre au sentiment d'être "animal" et "masculin" chez "homme ou femme". Puisque le niveau peut être spécifié par un nombre, le résultat est le même même si level = [0,2].
Enfin, je veux trouver la moyenne, alors ajoutez .mean ().
Le contenu du dictionnaire ressemble à ceci ↓
#Dans le programme ci-dessus.mean()Retirer et exécuter
m = df2['height'].xs([s, 'male'], level=['animal', 'male or female'])
#résultat
M
>
{'bird': color
white 10
Name: height, dtype: object,
'cat': color
black 20
white 25
brown 30
Name: height, dtype: object,
'dog': color
brown 90
Name: height, dtype: object}
Pour chaque animal, la valeur de «hauteur» correspondant au mâle (mâle) peut être obtenue.
Dans l'ordre, j'ai senti que je devais d'abord vérifier d'ici. Je pense que l'utilisation de .loc est la même que pour un DataFrame normal qui n'est pas Multiindex.
Examen des données
df2
>
age height weight
animal color male or female
cat black male 3 20 3.6
white male 5 25 4.5
female 5 26 4
brown male 5 30 5.2
female 4 22 3
dog black female 7 77 15.6
white female 8 55 10.5
brown male 10 90 20.1
bird white male 1 10 0.52
yellow female 2 15 0.89
Pour Index, spécifiez "chat" de "animal". Spécifiez tous les noms de colonne de Column.
df2.loc['cat']
#Ou
# df2.loc['cat', :]
>
age height weight
color male or female
black male 3 20 3.6
white male 5 25 4.5
female 5 26 4
brown male 5 30 5.2
female 4 22 3
Vous ne pouvez spécifier que les noms de colonne de Colonne que vous souhaitez affiner.
df2.loc['cat', ['height', 'weight']]
>
height weight
color male or female
black male 20 3.6
white male 25 4.5
female 26 4
brown male 30 5.2
female 22 3
Le premier argument est le libellé d'un niveau spécifique d'index et le deuxième argument est le nom de colonne de la colonne que vous souhaitez affiner.
df2.loc['cat', 'height']
>
color male or female
black male 20
white male 25
female 26
brown male 30
female 22
Name: height, dtype: object
Spécifiez plusieurs étiquettes dans le même niveau d'index.
df2.loc[['cat', 'bird'], 'height']
>
animal color male or female
cat black male 20
white male 25
female 26
brown male 30
female 22
bird white male 10
yellow female 15
Name: height, dtype: object
Cette fois, comment franchir le niveau d'index. Affinez-vous par ordre de niveau d'index (à partir de 0 en termes de nombres). Si rien n'est spécifié dans (), le résultat est le même que df2.loc [:, 'height'].
# 'cat'Quel est.
df2.loc[('cat'), 'height']
>
color male or female
black male 20
white male 25
female 26
brown male 30
female 22
Name: height, dtype: object
# 'cat'De'white'Quel est.
df2.loc[('cat','white'), 'height']
>
male or female
male 25
female 26
Name: height, dtype: object
# 'cat'De'white'Est'male'Quel est.
df2.loc[('cat','white','male'), 'height']
> 25
Si vous vous restreignez à ce point, vous pouvez réécrire la valeur.
df3 = df2.copy()
#Suppléant 30
df3.loc[('cat','white','male'), 'height'] = 30
df3.loc[('cat','white','male'), 'height']
> 30
Il semble que les tranches peuvent également être utilisées, mais si vous le faites sans réfléchir, l'erreur suivante se produira
df2.loc[('cat','brown','male'):('dog','black','female')]
> UnsortedIndexError: 'Key length (3) was greater than MultiIndex lexsort depth (0)'
Solution Trier à l'aide de .sort_index ().
df5 = df2.sort_index(level=0)
df5
>
age height weight
animal color male or female
bird white male 1 10 0.52
yellow female 2 15 0.89
cat black male 3 20 3.6
brown female 4 22 3
male 5 30 5.2
white female 5 26 4
male 5 25 4.5
dog black female 7 77 15.6
brown male 10 90 20.1
white female 8 55 10.5
Spécifiez niveau = nombre comme argument. Puisque le niveau = 0 a été spécifié cette fois, il est trié en fonction de l'étiquette de l'animal.
df5.loc[('cat','brown','male'):('dog','black','female')]
>
age height weight
animal color male or female
cat brown male 5 30 5.2
white female 5 26 4
male 5 25 4.5
dog black female 7 77 15.6
('cat', 'brown'): la plage est réduite à ('dog', 'white').
pd.indexSlice
idx = pd.IndexSlice
df5.loc[idx[:, :, ['male']], 'height']
>
animal color male or female
bird white male 10
cat black male 20
brown male 30
white male 25
dog brown male 90
Name: height, dtype: object
En regardant uniquement le résultat de sortie, la taille mâle de chaque animal peut être extraite comme dans le cas de l'utilisation de .xs (). Donc, si vous voulez obtenir le même résultat qu'en utilisant .xs (), faites ceci. a = ['bird', 'cat', 'dog']
# pd.Utiliser la tranche d'index
M_idx = {}
for s in a:
M_idx[s] = df5.loc[idx[[s], :, ['male']], 'height'].mean()
M_idx
> {'bird': 10.0, 'cat': 25.0, 'dog': 90.0}
Comparaison avec l'utilisation de .xs ()
# .xs()utilisation
M = {}
for s in a:
M[s] = df2['height'].xs([s, 'male'], level=['animal', 'male or female']).mean()
M
> {'bird': 10.0, 'cat': 25.0, 'dog': 90.0}
Lequel utiliser semble être une préférence personnelle
Je pense que Multiindex peut être utilisé de différentes manières une fois que je m'y suis habitué, mais je ne sais toujours pas comment l'utiliser. Plus tard, il peut y avoir des fluctuations typographiques ou des erreurs typographiques que j'ai négligées, je vais donc les corriger.
MultiIndex / advanced indexing
Recommended Posts