.. index:: Pandas .. _Pandas: ``pandas`` -- eine Bibliothek für tabellarische Daten ===================================================== Pandas ist eine Python-Bibliothek, die vorrangig zum Auswerten und Bearbeiten tabellarischer Daten gedacht ist. Dafür sind in Pandas drei Arten von Objekten definiert: * Eine ``Series`` entspricht in vielerlei Hinsicht einer "eindimensionalen" Liste, beispielsweise einer Zeitreihe, einer Liste, einem Dict, oder einem :ref:`Numpy ` -Array. * Ein ``Dataframe`` besteht aus einer "zweidimensionalen" Tabelle. Die einzelnen Reihen beziehungsweise Spalten dieser Tabelle können wie ``Series``-Objekte bearbeitet werden. * Ein ``Panel`` besteht aus einer "dreidimensionalen" Tabelle. Die einzelnen Ebenen dieser Tabelle bestehen wiederum aus ``Dataframe``-Objekten. In den folgenden Abschnitten sollen in Anlehnung an das berühmte `10 minutes to pandas `__-Tutorial die ``Series``- und die ``Dataframe``-Objekte als grundlegende und am häufigsten verwendeten Pandas-Objekte kurz vorgestellt werden. .. index:: Series() .. _Arbeiten mit Series-Objekten: .. _Series: Arbeiten mit ``Series``-Objekten -------------------------------- Ein neues Series-Objekt kann mittels der gleichnamigen Funktion beispielsweise aus einer gewöhnlichen Liste generiert werden: .. code-block:: python import pandas as pd s = pd.Series( [5,10,15,20,25] ) s # Ergebnis: # 0 5 # 1 10 # 2 15 # 3 20 # 4 25 # dtype: int64 Das Series-Objekt erhält automatisch einen Index, so dass beispielsweise mittels ``s[0]`` auf das erste Element, mit ``s[1]`` auf das zweite Element, usw. zugegriffen werden kann. Neben diesen numerischen Indizes, die auch bei gewöhnlichen Listen verwendet werden, können explizit auch andere Indizes vergeben werden: .. code-block:: python s.index = ['a','b','c','d','e'] s # Ergebnis: # a 5 # b 10 # c 15 # d 20 # e 25 # dtype: int64 Nun können die einzelnen Elemente zwar immer noch mit ``s[0]``, ``s[1]``, usw., aber zusätzlich auch mittels ``s['a']``, ``s['b']`` usw. ausgewählt werden. [#]_ Wird bei der Generierung eines Series-Objekts ein :ref:`Dict ` angegeben, so werden automatisch die Schlüssel als Indizes und die Werte als eigentliche Listenelemente gespeichert. .. _Slicings: .. rubric:: Slicings Sollen mehrere Elemente ausgewählt werden,so können die entsprechenden Indizes wahlweise als Liste oder als so genannter "Slice" angegeben werden: .. code-block:: python # Zweites und drittes Element auswählen: s[ [1,2] ] # Ergebnis: # b 10 # c 15 # Identische Auswahl mittels Slicing: s[ 1:3 ] # Ergebnis: # b 10 # c 15 Bei Slicings wird, ebenso wie bei :ref:`range() `-Angaben, die obere Grenze nicht in den Auswahlbereich mit eingeschlossen. Die Auswahl mittels Slicing hat bei Series-Objekten also die gleiche Syntax wie die :ref:`Auswahl von Listenobjekten `. .. index:: Zeitreihe, date_range() .. _Zeitreihen: .. rubric:: Zeitreihen Zeitangaben in Series-Objekten können mittels der Pandas-Funktion ``date_range()`` generiert werden: .. code-block:: python dates = pd.date_range('2000-01-01', '2000-01-07') dates # # [2000-01-01, ..., 2000-01-07] # Length: 7, Freq: D, Timezone: None Als Start- und Endpunkt werden allgemein Datumsangaben mit einer gleichen Syntax wie im ``datetime``-Modul verwendet. Zusätzlich kann angegeben werden, in welchen Zeitschritten die Zeitreihe erstellt werden soll: .. code-block:: python weekly = pd.date_range('2000-01-01', '2000-02-01', freq="W") weekly # Ergebnis: # # [2000-01-02, ..., 2000-01-30] # Length: 5, Freq: W-SUN, Timezone: None hourly = pd.date_range('2000-01-01 8:00', '2000-01-01 18:00', freq="H") hourly # Ergebnis: # # [2000-01-01 08:00:00, ..., 2000-01-01 18:00:00] # Length: 11, Freq: H, Timezone: None Die Elemente der Zeitreihe können explizit mittels ``list(zeitreihe``, beispielsweise ``list(dates)``, ausgegeben werden; in Series-Objekten werden Zeitreihen häufig als Index-Listen verwendet. .. _Arbeiten mit Dataframe-Objekten: .. _Dataframe: Arbeiten mit ``Dataframe``-Objekten ----------------------------------- .. index:: Dataframe() Ein neues Dataframe-Objekt kann mittels der Funktion ``DataFrame()`` beispielsweise aus einer gewöhnlichen Liste generiert werden: .. code-block:: python import pandas as pd # 1D-Beispiel-Dataframe erstellen: df = pd.DataFrame( [5,10,15,20,25] ) df # Ergebnis: # 0 # 0 5 # 1 10 # 2 15 # 3 20 # 4 25 # # [5 rows x 1 columns] Als Unterschied zu einem Series-Objekt werden bei einem Dataframe sowohl die Zeilen als auch die Spalten mit einem Index versehen. Mehrspaltige Dataframes können auch über ein ``dict``-Objekt definiert werden, wobei die Schlüsselwerte den Spaltennamen und die damit verbundenen Werte einzelnen Daten entsprechen, aus denen der Dataframe generiert werden soll: .. code-block:: python # 2D-Beispiel-Dataframe erstellen: df2 = pd.DataFrame({ 'A' : 1., 'B' : pd.date_range('2000-01-01', '2000-01-07'), 'C' : pd.Series(range(7), dtype='float32'), 'D' : np.random.randn(7), 'E' : pd.Categorical(['on', 'off', 'on', 'off', 'on', 'off', 'on']), 'F' : 'foo' }) df2 # Ergebnis: # A B C D E F # 0 1 2000-01-01 0 -2.611072 on foo # 1 1 2000-01-02 1 0.630309 off foo # 2 1 2000-01-03 2 -1.645430 on foo # 3 1 2000-01-04 3 1.056535 off foo # 4 1 2000-01-05 4 2.194970 on foo # 5 1 2000-01-06 5 0.537804 off foo # 6 1 2000-01-07 6 1.011678 on foo Wie man sieht, wird bei Angabe eines einzelnen Wertes für eine Spalte dieser als konstant für die ganze Spalte angenommen; listenartige Objekte hingegen müssen allesamt die gleiche Länge aufweisen. .. rubric:: Datentypen Innerhalb einer Spalte eines Dataframe-Objekts müssen alle Werte den gleichen Datentyp aufweisen. Man kann sich die Datentypen der einzelnen Spalten folgendermaßen anzeigen lassen: .. code-block:: python # Datentypen anzeigen: df2.dtypes # Ergebnis: # A float64 # B datetime64[ns] # C float32 # D float64 # E category # F object # dtype: object .. _Daten anzeigen und sortieren: Daten anzeigen und sortieren ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Bei längeren Datensätzen kann es bereits hilfreich sein, nur einen kurzen Blick auf den Anfang oder das Ende der Tabelle werfen zu können. Bei Dataframe-Objekten ist dies mittels der Funktionen ``head()`` beziehungsweise ``tail()`` möglich: .. code-block:: python # Die ersten fünf Zeilen des Dataframes anzeigen: df2.head() # Ergebnis: # A B C D E F # 0 1 2000-01-01 0 -2.611072 on foo # 1 1 2000-01-02 1 0.630309 off foo # 2 1 2000-01-03 2 -1.645430 on foo # 3 1 2000-01-04 3 1.056535 off foo # 4 1 2000-01-05 4 2.194970 on foo # Die letzten drei Zeilen des Dataframes anzeigen: df2.tail(3) # Ergebnis: # A B C D E F # 4 1 2000-01-05 4 2.194970 on foo # 5 1 2000-01-06 5 0.537804 off foo # 6 1 2000-01-07 6 1.011678 on foo Standardmäßig geben ``head()`` und ``tail()`` je fünf Zeilen aus; ist eine andere Anzahl gewünscht, so kann diese als Argument angegeben werden. .. rubric:: Spalten und Index-Werte Die einzelnen Bestandteile eines Dataframes, d.h. die Spaltennamen, die Index-Werte sowie die eigentlichen Daten, können über die Attribute ``columns``, ``index`` und ``values`` des Dataframes abgerufen werden: .. code-block:: python # Spaltennamen, Index-Werte und Inhalt des Dataframes ausgeben: df2.columns # Ergebnis: # Index(['A', 'B', 'C', 'D', 'E', 'F'], dtype='object') df2.index # Ergebnis: # Int64Index([0, 1, 2, 3, 4, 5, 6], dtype='int64') df2.values # Ergebnis: # array([[1.0, Timestamp('2000-01-01 00:00:00'), 0.0, -2.611072451193798, 'on', 'foo'], # [1.0, Timestamp('2000-01-02 00:00:00'), 1.0, 0.6303090119623712, 'off', 'foo'], # [1.0, Timestamp('2000-01-03 00:00:00'), 2.0, -1.645429619256174, 'on', 'foo'], # [1.0, Timestamp('2000-01-04 00:00:00'), 3.0, 1.056535156797566, 'off', 'foo'], # [1.0, Timestamp('2000-01-05 00:00:00'), 4.0, 2.1949702833421596, 'on', 'foo'], # [1.0, Timestamp('2000-01-06 00:00:00'), 5.0, 0.5378036597920774, 'off', 'foo'], # [1.0, Timestamp('2000-01-07 00:00:00'), 6.0, 1.01167812002758, 'on', 'foo']], # dtype=object) .. rubric:: Statistische Übersicht Eine Kurz-Analyse der Daten ist über die Methode ``describe()`` des Dataframes möglich. Man erhält als Ergebnis eine Übersicht über die jeweiligen Mittelwerte sowie einige statistische Streuungsmaße (Standardabweichung, größter und kleinster Wert, Quartile). Da sich diese Größen nur für quantitative (genauer: invervall-skalierte) Merkmalswerte bestimmen lassen, werden die jeweiligen Werte auch nur für die in Frage kommenden Spalten angezeigt: .. code-block:: python # Statistische Kurz-Info anzeigen: df2.describe() # Ergebnis: # A C D # count 7 7.000000 7.000000 # mean 1 3.000000 0.167828 # std 0 2.160247 1.681872 # min 1 0.000000 -2.611072 # 25% 1 1.500000 -0.553813 # 50% 1 3.000000 0.630309 # 75% 1 4.500000 1.034107 # max 1 6.000000 2.194970 .. rubric:: Sortiermethoden Die Daten eines Dataframes können zudem wahlweise nach Zeilen oder Spalten oder auch anhand der jeweiligen Werte sortiert werden: * Mit der Methode ``sort_index()`` können die Daten nach Zeilen (``axis=0``) oder Spalten (``axis=1``) sortiert werden; mittels ``ascending=False`` kann zudem die Reihenfolge der Sortierung umgekehrt werden. .. code-block:: python df2.sort_index(axis=1, ascending=False) # Ergebnis: # F E D C B A # 0 foo on -2.611072 0 2000-01-01 1 # 1 foo off 0.630309 1 2000-01-02 1 # 2 foo on -1.645430 2 2000-01-03 1 # 3 foo off 1.056535 3 2000-01-04 1 # 4 foo on 2.194970 4 2000-01-05 1 # 5 foo off 0.537804 5 2000-01-06 1 # 6 foo on 1.011678 6 2000-01-07 1 Wird zusätzlich das optionale Argument ``inline=True`` gesetzt, so wird nicht ein verändertes Resultat angezeigt (das beispielsweise in einer neuen Variablen gespeichert werden könnte); vielmehr wird in diesem Fall die Änderung auch im ursprünlichen Dataframe-Objekt übernommen. * Mit der Methode ``sort_value()`` können die Daten ihrer Größe nach sortiert werden. Standardmäßig werden die Daten dabei zeilenweise (``axis=0``) und in aufsteigender Reihenfolge (``ascending=True``) sortiert; bei Bedarf können diese Variablen angepasst werden. .. code-block:: python df2.sort_values(by='D') # Ergebnis: # A B C D E F # 0 1 2000-01-01 0 -2.611072 on foo # 2 1 2000-01-03 2 -1.645430 on foo # 5 1 2000-01-06 5 0.537804 off foo # 1 1 2000-01-02 1 0.630309 off foo # 6 1 2000-01-07 6 1.011678 on foo # 3 1 2000-01-04 3 1.056535 off foo # 4 1 2000-01-05 4 2.194970 on foo Auch bei dieser Sortiermethode können die Änderungen mittels ``inline=True`` nicht nur angezeigt, sondern direkt in den Original-Dataframe übernommen werden. Daten auswählen ^^^^^^^^^^^^^^^ Dataframe-Objekte ähneln in gewisser Hinsicht ``dict``-Objekten: Die einzelnen Spalten beziehungsweise Zeilen können mithilfe des Spalten- beziehungsweise Index-Namens ausgewählt werden. Ein Zugriff auf einzelne Zeilen oder Spalten ist beispielsweise mit Hilfe des Index-Operators ``[ ]`` möglich. Gibt man hierbei einen Spaltennamen an, so wird die jeweilige Spalte ausgewählt; gibt man hingegen eine Zeilennummer oder einen Zeilenbereich an, so erhält man die jeweilige(n) Zeile(n) als Ergebnis: .. code-block:: python df2['B'] # Ergebnis: # 0 2000-01-01 # 1 2000-01-02 # 2 2000-01-03 # 3 2000-01-04 # 4 2000-01-05 # 5 2000-01-06 # 6 2000-01-07 # Name: B, dtype: datetime64[ns] df2[1:3] # A B C D E F # 1 1 2000-01-02 1 0.630309 off foo # 2 1 2000-01-03 2 -1.645430 on foo .. ---- .. Auswahl mittels ``df.loc()``: Sinnvoll, wenn die Zeilen nicht automatisch .. nummeriert sind, sondern als andere Werte festgelegt wurden. In diesem Fall .. wäre kein Zugriff mehr via df[0:3] möglich; stattdessen .. df.loc['ilabel1':'ilabel2'] .. dfl = pd.DataFrame(np.random.randn(5,4), columns=list('ABCD'), index=pd.date_range('20130101',periods=5)) .. http://pandas.pydata.org/pandas-docs/stable/indexing.html#indexing-label .. purely label based indexing: .. When slicing, the start bound is included, AND the stop bound is included. .. Integers are valid labels, but they refer to the label and not the position. .. The .loc attribute is the primary access method. The following are valid inputs: .. * A single label, e.g. 5 or 'a', (note that 5 is interpreted as a label of the .. index. This use is not an integer position along the index) .. * A list or array of labels ['a', 'b', 'c'] .. * A slice object with labels 'a':'f' (note that contrary to usual python slices, .. both the start and the stop are included!) .. Setting works as well! .. ---- Fehlende Werte ^^^^^^^^^^^^^^ ... to be continued ... .. raw:: html
.. only:: html .. rubric:: Anmerkungen: .. [#] Die Index-Liste kann auch bereits bei der Erzeugung eines neuen Series-Objekts mittels ``Series(datenliste, index=indexliste)`` angegeben werden. .. .. [#] Quellen für tabellarische Daten: .. Allgemeine Statistiken: .. Das Statistische Bundesamt gibt jährlich ein umfangreiches `statistisches .. Jahrbuch .. `__ .. heraus; zudem können zu verschiedenen `Fachthemen .. `__ .. PDF- beziehungsweise XLS-Dateien heruntergeladen werden. .. Klima- und Wetterdaten: .. Der Deutsche Wetterdienst (DWD) gibt kostenlos `Klimadaten .. `__ .. von verschiedenen Mess-Stationen heraus. Es können sowohl Tages- wie auch .. Monats-Werte oder sogar langjährige Daten-Tabellen ausgewählt und/oder .. heruntergeladen werden. .. Prozess- und Produktdaten: .. Das Bundesamt für Umwelt gibt unter der Bezeichnung `GEMIS .. `__ beziehungsweise `ProBas .. `__ eine Datenbank .. beziehungsweise eine darauf aufbauende Webbrowser-Applikation heraus, in der .. für eine Vielzahl von Handelsprodukten aufgelistet ist, welcher Energie- und .. Rohstoffbedarf bei der Herstellung notwendig ist. .. Energie-Daten .. Das Bundesamt für Wirtschaft stellt eine regelmäßig aktualisierte Statistik zu .. `Energie-Daten .. `__ .. (Energieverwendung, Energiekosten, Ressourcen, usw.) als PDF- beziehungsweise .. XLS-Datei zum Herunterladen zur Verfügung.