Multi-Level Indizierung

Einführung

Multi Level Indizierung

Die Basiskonzepte von Pandas haben wir im vorherigen Kapitel gelernt. Dabei haben wir uns die Daten-Strukturen

angeschaut.

Ebenso haben wir gelernt, wie man Series- und DataFram-Objekte in numerischen Python-Programmen erstellt und manipuliert.

Jetzt wollen wir weitere Aspekte dieser Datenstrukturen betrachen. Wir beginnen mit den fortgeschrittenen Indizierungsmöglichkeiten in Pandas.

Fortgeschrittene oder Multi-Level Indizierung

Fortgeschrittenes oder Multi-Level Indizierung ist sowohl für Series, als auch für DataFrame verfügbar. Es ist eine faszinierende Möglichkeit in höheren Daten-Dimensionen mit den Pandas-Datenstrukturen zu arbeiten. Ein effizienter Weg um beliebig hoch dimensionierte Daten zu speichern und zu manipulieren und damit in 1-dimensionalen (Series) oder 2-dimensionalen (DataFrames) Strukturen zu arbeiten. Mit anderen Worten können wir mit höheren Dimensionen arbeiten über die tieferen Dimensionen. Es ist Zeit für ein Beispiel in Python:

import pandas as pd
cities = ["Vienna", "Vienna", "Vienna",
          "Hamburg", "Hamburg", "Hamburg",
          "Berlin", "Berlin", "Berlin",
          "Zürich", "Zürich", "Zürich"]
index = [cities, ["country", "area", "population",
                  "country", "area", "population",
                  "country", "area", "population",
                  "country", "area", "population"]]
print(index)
[['Vienna', 'Vienna', 'Vienna', 'Hamburg', 'Hamburg', 'Hamburg', 'Berlin', 'Berlin', 'Berlin', 'Zürich', 'Zürich', 'Zürich'], ['country', 'area', 'population', 'country', 'area', 'population', 'country', 'area', 'population', 'country', 'area', 'population']]
data = ["Austria", 414.60,    1805681,
        "Germany", 755.00,    1760433,
        "Germany", 891.85,    3562166,
        "Switzerland", 87.88, 378884]
city_series = pd.Series(data, index=index)
print(city_series)
Vienna   country           Austria
         area                414.6
         population        1805681
Hamburg  country           Germany
         area                  755
         population        1760433
Berlin   country           Germany
         area               891.85
         population        3562166
Zürich   country       Switzerland
         area                87.88
         population         378884
dtype: object

Wir können über folgenden Weg auf die Daten zugreifen:

print(city_series["Vienna"])
country       Austria
area            414.6
population    1805681
dtype: object

Ebenso kann auf die Information über das Land (country), Gebiet (area) oder Bevölkerung (population) einer Stadt zugegriffen werden. Dazu gibt es zwei Möglichkeiten:

print(city_series["Vienna"]["area"])
414.6

Zur Vervollständigung der zweite Weg:

print(city_series["Vienna", "area"])
414.6

Es können auch Inhalte mehrerer Städte gleichzeitig ausgelesen werden, indem man eine Liste der Stadtnamen als Schlüssel verwendet:

city_series[["Vienna","Berlin"]]
Wir können die folgende Ausgabe erwarten, wenn wir den obigen Python-Code ausführen:
Vienna  country       Austria
        area            414.6
        population    1805681
Berlin  country       Germany
        area           891.85
        population    3562166
dtype: object

Wenn der Index sortiert/geordnet ist, kann auch die Slicing-Operation angewendet werden:

city_series = city_series.sort_index()
print("city_series with sorted index:")
print(city_series)
print("\n\nSlicing the city_series:")
city_series["Berlin":"Vienna"]
city_series with sorted index:
Berlin   area               891.85
         country           Germany
         population        3562166
Hamburg  area                  755
         country           Germany
         population        1760433
Vienna   area                414.6
         country           Austria
         population        1805681
Zürich   area                87.88
         country       Switzerland
         population         378884
dtype: object
Slicing the city_series:
Führt man obigen Code aus, erhält man folgende Ausgabe:
Berlin   area           891.85
         country       Germany
         population    3562166
Hamburg  area              755
         country       Germany
         population    1760433
Vienna   area            414.6
         country       Austria
         population    1805681
dtype: object

Im nächsten Beispiel zeigen wir, dass auf die inneren Schlüssel auch zugegriffen werden kann:

print(city_series[:, "area"])
Berlin     891.85
Hamburg       755
Vienna      414.6
Zürich      87.88
dtype: object

Umlegen/Tauschen der MultiIndex Level

Es ist möglich die Level eines MultiIndex mit der Methode swaplevel() umzulegen bzw. zu tauschen:

help(pd.Series.swaplevel)
Help on function swaplevel in module pandas.core.series:
swaplevel(self, i=-2, j=-1, copy=True)
    Swap levels i and j in a MultiIndex
    
    Parameters
    ----------
    i, j : int, string (can be mixed)
        Level of index to be swapped. Can pass level name as string.
    
    Returns
    -------
    swapped : Series
    
    .. versionchanged:: 0.18.1
    
       The indexes ``i`` and ``j`` are now optional, and default to
       the two innermost levels of the index.
print(city_series)
city_series = city_series.swaplevel()
city_series.sort_index(inplace=True)
print("\n---Swapped---")
city_series
area        Berlin          891.85
            Hamburg            755
            Vienna           414.6
            Zürich           87.88
country     Berlin         Germany
            Hamburg        Germany
            Vienna         Austria
            Zürich     Switzerland
population  Berlin         3562166
            Hamburg        1760433
            Vienna         1805681
            Zürich          378884
dtype: object
---Swapped---
Wir erhalten die folgende Ergebnisse:
Berlin   area               891.85
         country           Germany
         population        3562166
Hamburg  area                  755
         country           Germany
         population        1760433
Vienna   area                414.6
         country           Austria
         population        1805681
Zürich   area                87.88
         country       Switzerland
         population         378884
dtype: object