Klicken Sie hier für Details ↓ https://pandas.pydata.org/pandas-docs/stable/user_guide/advanced.html Dem Dokument zufolge handelt es sich um einen hierarchischen Index, der (grob) bei der Bearbeitung hochdimensionaler Daten verwendet werden kann.
Das Panel, das die 3D-Datenstruktur in Pandas behandelt, wurde abgeschafft. Überprüfen Sie daher, wie Sie hier damit umgehen. Da es sich um ein persönliches Memorandum handelt, ist es überhaupt nicht erschöpfend. Wenn Sie also Fragen haben, müssen Sie diese gegebenenfalls untersuchen.
python 3.7.7 pandas 1.1.1 Ausführungsumgebung: Jupyter Notebook
Wie erwartet können Forschungsdaten nicht verwendet werden, daher werden Beispieldaten entsprechend erstellt.
#Pandas importieren
import pandas as pd
#Datenerstellung
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]]
#In DataFrame konvertieren.Inversion von Zeilen und Spalten mit T.
df = pd.DataFrame(array).T
#Spalteneinstellungen
df.columns = ['animal','color','male or female','age','height','weight']
So was. Da der Inhalt implizit erstellt wird, scheint es eine sehr fettleibige Katze zu geben.
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 |
Nebenbei: Mit .to_markdown () können Sie eine Tabelle mit Markdown-Notation erstellen. Es scheint, dass es von 1.0.0 oder höher von Pandas implementiert wurde? Am Ende ist jedoch .to_html () verschuldet.
index So legen Sie den Index fest und setzen ihn zurück
Der durch set_index angegebene Spaltenname ist der Index der Ebene ab 0 von 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 |
Die Indexstufen können übrigens in beliebiger Reihenfolge eingestellt werden.
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 |
Im Vergleich zur obigen Tabelle kann bestätigt werden, dass die Werte der ersten und zweiten Ebene vertauscht sind.
Als Randnotiz hat .set_index () als Parameter drop, der standardmäßig True ist. Dies gibt an, ob die Daten der als Index verwendeten Spalte gelöscht werden sollen. Wenn drop = False ist, bleiben die Daten der in Index angegebenen Spalte unverändert wie unten gezeigt.
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 |
So was. Grundsätzlich scheint es kein Problem mit der Standardeinstellung zu geben, sodass Sie sich darüber keine Sorgen machen müssen.
Verwenden Sie zum Zurücksetzen des Index .reset_index ().
df1 = df2.reset_index()
Wenn Sie df und df1 vergleichen, können Sie sehen, dass die Tabelle dieselbe ist.
Bestätigung, dass der in Index angegebene Spaltenname wahrscheinlich in Namen enthalten ist.
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'])
Ich frage mich, ob es verwendet werden kann, wenn der Spaltenname in Index überprüft wird.
df2.index.names
>
FrozenList(['animal', 'color', 'male or female'])
Von hier aus werden wir df2 verwenden, um verschiedene Dinge zu sehen.
Verwenden Sie .index.get_level_values (). Dies gibt eine Bezeichnung einer bestimmten Ebene als Vektor zurück.
#Wird durch einen bestimmten Spaltennamen der Ebene angegeben
df2.index.get_level_values('animal')
> Index(['cat', 'cat', 'cat', 'cat', 'cat', 'dog', 'dog', 'dog', 'bird', 'bird'], dtype='object', name='animal')
Gleiches Ergebnis wie oben ↓
#Kann auch durch die Levelnummer angegeben werden
df2.index.get_level_values(0)
> Index(['cat', 'cat', 'cat', 'cat', 'cat', 'dog', 'dog', 'dog', 'bird', 'bird'], dtype='object', name='animal')
Vermeiden Sie Duplikate mit set, konvertieren Sie sie in eine Liste und sortieren Sie sie, um eine neue Liste zu erstellen. Wenn Sie absteigende Reihenfolge verwenden möchten, setzen Sie das Argument umgekehrt auf True. (Ich denke nicht, dass es hier viel Sinn macht.)
#Etikett ohne Vervielfältigung erhalten
a = sorted(list(set(df2.index.get_level_values('animal'))))
a
> ['bird', 'cat', 'dog']
Mit .xs () können Sie den Namen der Indexspalte und ihren Wert (Bezeichnung) für die Auswahl oder Extraktion angeben.
Verwenden wir die zuvor erstellte Liste, um die Funktionsweise von xs () zu überprüfen. Der Inhalt ist ['Vogel', 'Katze', 'Hund'] ← Verwenden Sie die Werte in dieser Liste als Schlüssel, um die durchschnittliche Größe für jedes männliche und weibliche Tier zu ermitteln.
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
#Ergebnis
M
> {'bird': 10.0, 'cat': 25.0, 'dog': 90.0}
F
> {'bird': 15.0, 'cat': 24.0, 'dog': 66.0}
Zusätzlich zu .mean (), .min (), .max (), .std (), .count () usw. können je nach Zweck verwendet werden.
Vorerst Kommentar
Geben Sie zunächst den Spaltennamen des Werts an, den Sie suchen möchten (diesmal möchte ich den Durchschnitt der Höhe ermitteln). df2['height']
Verwenden Sie als Nächstes .xs (), um detaillierte Spezifikationen zu erstellen. df2['height'].xs([s, 'male'], level=['animal', 'male or female'])
Erstens über [s, 'männlich']. Um diesmal die durchschnittliche Größe jedes Mannes (männlich) und jeder Frau (weiblich) jedes Tieres zu berechnen, geben Sie im ersten Argument von .xs () ein Etikett an, das der Information "welches Tier und welches Geschlecht" entspricht.
Als nächstes ungefähr Level = ['Tier', 'männlich oder weiblich']. Dies scheint auf die zuvor angegebene Stufe von [s, 'männlich'] hinzuweisen. Es ist also gut, dem Gefühl von s in'animal'and'male 'in' male or female 'zu entsprechen. Da die Ebene durch eine Zahl angegeben werden kann, ist das Ergebnis auch dann gleich, wenn die Ebene = [0,2] ist.
Schließlich möchte ich den Durchschnitt finden, also füge .mean () hinzu.
Der Inhalt des Wörterbuchs sieht folgendermaßen aus ↓
#Im obigen Programm.mean()Entfernen und ausführen
m = df2['height'].xs([s, 'male'], level=['animal', 'male or female'])
#Ergebnis
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}
Für jedes Tier kann der Wert der "Höhe" erhalten werden, der dem Männchen (Männchen) entspricht.
Um das Gefühl zu haben, sollte ich zuerst von hier aus nachsehen. Ich denke, die Verwendung von .loc ist die gleiche wie für einen normalen DataFrame, der kein Multiindex ist.
Datenüberprüfung
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
Geben Sie für Index 'cat'of'animal' an. Geben Sie alle Spaltennamen der Spalte an.
df2.loc['cat']
#Oder
# 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
Sie können nur die Spaltennamen der Spalte angeben, die Sie eingrenzen möchten.
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
Das erste Argument ist die Bezeichnung einer bestimmten Indexebene, und das zweite Argument ist der Spaltenname der Spalte, die Sie eingrenzen möchten.
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
Geben Sie mehrere Beschriftungen innerhalb derselben Indexebene an.
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
Dieses Mal, wie man die Indexebene überschreitet. Eingrenzen in der Reihenfolge des Indexniveaus (von 0 in Zahlen). Wenn in () nichts angegeben ist, ist das Ergebnis dasselbe wie df2.loc [:, 'height'].
# 'cat'Was ist.
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'Von'white'Was ist.
df2.loc[('cat','white'), 'height']
>
male or female
male 25
female 26
Name: height, dtype: object
# 'cat'Von'white'Ist'male'Was ist.
df2.loc[('cat','white','male'), 'height']
> 25
Wenn Sie auf diesen Punkt eingrenzen, können Sie den Wert neu schreiben.
df3 = df2.copy()
#Ersatz 30
df3.loc[('cat','white','male'), 'height'] = 30
df3.loc[('cat','white','male'), 'height']
> 30
Es scheint, dass auch Slices verwendet werden können, aber wenn Sie dies ohne nachzudenken tun, tritt der folgende Fehler auf
df2.loc[('cat','brown','male'):('dog','black','female')]
> UnsortedIndexError: 'Key length (3) was greater than MultiIndex lexsort depth (0)'
Lösungen Sortieren Sie mit .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
Geben Sie als Argument level = number an. Da diesmal Level = 0 angegeben wurde, wird es basierend auf dem Tieretikett sortiert.
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
('Katze', 'Braun'): Der Bereich wird auf ('Hund', 'Weiß') eingegrenzt.
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
Betrachtet man nur das Ausgabeergebnis, kann die männliche "Höhe" für jedes Tier wie bei Verwendung von .xs () extrahiert werden. Wenn Sie also das gleiche Ergebnis wie mit .xs () erzielen möchten, tun Sie dies. a = ['bird', 'cat', 'dog']
# pd.Verwenden Sie Index Slice
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}
Vergleich mit .xs ()
# .xs()verwenden
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}
Welches zu verwenden scheint, scheint persönliche Präferenz zu sein
Ich habe das Gefühl, dass Multiindex auf verschiedene Arten verwendet werden kann, sobald ich mich daran gewöhnt habe, aber ich bin mir immer noch nicht sicher, wie ich es verwenden soll. Später kann es zu typografischen Schwankungen oder typografischen Fehlern kommen, die ich übersehen habe, sodass ich sie korrigieren werde.
MultiIndex / advanced indexing
Recommended Posts