[PYTHON] Verwendung von MultiIndex (persönliches Memorandum)

Was ist MultiIndex?

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.

Umwelt etc.

python 3.7.7 pandas 1.1.1 Ausführungsumgebung: Jupyter Notebook

Bestätigung der Daten

Wie erwartet können Forschungsdaten nicht verwendet werden, daher werden Beispieldaten entsprechend erstellt.

Daten erstellen

#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']

Dateninhalt

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.

Grundlegende Verwendung

index So legen Sie den Index fest und setzen ihn zurück

Indexeinstellung

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)
                                                                                                                                                                                                                                                 
animalcolormale or femaleageheightweight
animalcolormale or female
catblackmalecatblackmale3203.6
whitemalecatwhitemale5254.5
femalecatwhitefemale5264
brownmalecatbrownmale5305.2
femalecatbrownfemale4223
dogblackfemaledogblackfemale77715.6
whitefemaledogwhitefemale85510.5
brownmaledogbrownmale109020.1
birdwhitemalebirdwhitemale1100.52
yellowfemalebirdyellowfemale 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.

Index zurückgesetzt

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.

Bonus

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'])

Datenextraktion

Von hier aus werden wir df2 verwenden, um verschiedene Dinge zu sehen.

Extraktion von Werten, die in einer bestimmten Ebene enthalten sind

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

Etiketten ohne Vervielfältigung extrahieren

#Etikett ohne Vervielfältigung erhalten
a = sorted(list(set(df2.index.get_level_values('animal'))))
a

> ['bird', 'cat', 'dog']

Extrahieren Sie Werte mit .xs ()

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.

Extrahieren Sie Werte mit .loc

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

Bonus: Wertzuweisung

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

Geben Sie durch Slice & Notes an

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

abschließend

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.

Referenzseite

MultiIndex / advanced indexing

Recommended Posts

Verwendung von MultiIndex (persönliches Memorandum)
Verwendung von cron (persönliches Memo)
Memorandum über die Verwendung von Gremlin Python
Verwendung von xml.etree.ElementTree
Verwendung von virtualenv
Wie benutzt man Seaboan?
Verwendung von Image-Match
Wie man Shogun benutzt
Verwendung von Pandas 2
Verwendung von Virtualenv
Verwendung von numpy.vectorize
Verwendung von pytest_report_header
Wie man teilweise verwendet
Verwendung von SymPy
Wie man x-means benutzt
Verwendung von WikiExtractor.py
Verwendung von IPython
Verwendung von virtualenv
Wie benutzt man Matplotlib?
Verwendung von iptables
Wie benutzt man numpy?
Verwendung von TokyoTechFes2015
Wie benutzt man venv
Verwendung des Wörterbuchs {}
Wie benutzt man Pyenv?
Verwendung der Liste []
Wie man Python-Kabusapi benutzt
Verwendung von OptParse
Wie man Imutils benutzt
Verwendung der Suche sortiert
[gensim] Verwendung von Doc2Vec
Verstehen Sie, wie man Django-Filter verwendet
Verwendung des Generators
[Python] Verwendung von Liste 1
Verwendung von FastAPI ③ OpenAPI
Wie benutzt man Python Argparse?
Verwendung von IPython Notebook
Wie man Pandas Rolling benutzt
[Hinweis] Verwendung von virtualenv
Verwendung von Redispy-Wörterbüchern
Python: Wie man pydub benutzt
[Python] Verwendung von checkio
[Go] Verwendung von "... (3 Perioden)"
So bedienen Sie GeoIp2 von Django
[Python] Verwendung von input ()
Wie benutzt man den Dekorateur?
[Einführung] Verwendung von open3d
Wie benutzt man Python Lambda?
So verwenden Sie Jupyter Notebook
[Python] Verwendung von virtualenv
python3: Verwendung der Flasche (3)
So verwenden Sie Google Colaboratory
Verwendung von Python-Bytes
Python: So verwenden Sie Async mit
Verwendung der Zip-Funktion
Verwendung des optparse-Moduls
Zusammenfassung der Verwendung von pandas.DataFrame.loc
So installieren und verwenden Sie Tesseract-OCR