Einführung in die Pandas
Pandas ist eine kostenlose Open-Source-Python-Bibliothek, die unter der BSD-Lizenz veröffentlicht wird. Ursprünglich von Wes McKinney im Jahr 2008 entwickelt und von Unternehmen wie Intel und Nvidia unterstützt, zielt es auf die Datenanalyse und -manipulation ab. Es kann problemlos zum Lesen und Schreiben von Daten aus einer Vielzahl von Quellen wie Excel-Tabellen, CSV-Dateien (Comma-separated Values) und vielen mehr verwendet werden.
In diesem Tutorial untersuchen wir die grundlegenden Konzepte hinter Pandas und lernen, wie man tabellarische Daten bearbeitet und Statistiken und Diagramme erstellt.
In diesem Tutorial lernen Sie:
- So installieren Sie die Pandas-Bibliothek
- Bearbeiten von Tabellendaten
- So erstellen Sie Statistiken
- So erstellen Sie Diagramme
Installation
Die Pandas-Bibliothek ist in den offiziellen Repositories aller am häufigsten verwendeten Linux-Distributionen verfügbar. Um Pandas auf Fedora zu installieren, verwenden wir den dnf-Paketmanager:
sudo dnf install python3-pandas
Unter Debian und Derivaten können wir stattdessen apt verwenden:
sudo apt install python3-pandasUm das Paket unter Archlinux zu installieren, verwenden wir pacman:
sudo pacman -S python-pandasNative Installationen von Software über Paketmanager bieten die maximale Systemintegration; Manchmal kann es jedoch vorkommen, dass die Version einer Anwendung oder einer Bibliothek, die von einer Distribution verwaltet wird, gegenüber den Originalautoren zurückbleibt. In anderen Fällen benötigen wir möglicherweise eine bestimmte Version davon, vielleicht aus Kompatibilitätsgründen. In diesen Fällen ist der empfohlene Weg, Pandas zu installieren, die Verwendung von pip, dem Python-Paketmanager:
pip install pandasDiese Installationsmethode ist universell und erfordert keine Rechteausweitung. Mit pip können wir auch Pakete in projektspezifischen virtuellen Umgebungen installieren.
Der DataFrame
Die erste Klasse, mit der wir uns bei der Arbeit mit der Pandas-Bibliothek vertraut machen müssen, ist der DataFrame: Er wird verwendet, um eine zweidimensionale Datenstruktur darzustellen, die als Äquivalent einer SQL-Tabelle oder einer Excel-Tabelle angesehen werden kann. Später in diesem Tutorial werden wir sehen, wie ein DataFrame-Objekt initialisiert werden kann, indem Daten aus externen Quellen gelesen werden, wie wir sie gerade erwähnt haben. Im Moment sehen wir uns jedoch an, wie man eine von Grund auf neu erstellt.
Das Erstellen eines DataFrame von Grund auf ist ziemlich einfach. Eine Möglichkeit, dies zu tun, besteht darin, den Klassenkonstruktor aufzurufen und ein Wörterbuch als erstes Argument zu übergeben. Wenn wir Daten auf diese Weise übergeben, werden Wörterbuchschlüssel als Spaltenbeschriftungen verwendet, und die zugehörigen Werte werden verwendet, um die "Spalte" zu füllen. Lassen Sie uns dies anhand eines Beispiels verdeutlichen. Angenommen, wir möchten ein DataFrame-Objekt mit den folgenden Informationen zu einigen Charakteren aus dem Buch "Der Herr der Ringe" erstellen:
| Name | Alter | Rennen |
|---|---|---|
| Frodo | 50 | Hobbit |
| Galadriel | 8000 | Elfe |
| Aragorn | 87 | Mann |
Namen und Rassen werden durch Zeichenfolgen dargestellt, während Ganzzahlen verwendet werden, um das Alter der einzelnen Zeichen darzustellen. So könnten wir unseren DataFrame initialisieren:
import pandas as pd
data = {
"Name": ["Frodo", "Galadriel", "Aragorn"],
"Age": [50, 8000, 87],
"Race": ["Hobbit", "Elf", "Man"]
}
characters = pd.DataFrame(data)Alternativ können wir die gleichen Daten übergeben, indem wir eine Liste von Listen verwenden, von denen jede eine "Zeile" darstellt. Wenn wir das Objekt auf diese Weise initialisieren, müssen wir die Spaltenbeschriftungen explizit angeben, indem wir den Parameter columns verwenden:
data = [
['Frodo', 50, 'Hobbit'],
['Galadriel', 8000, 'Elf'],
['Aragorn', 87, 'Man']
]
characters = pd.DataFrame(data, columns=['Name', 'Age', 'Race'])Um eine "hübsche" Darstellung eines DataFrame-Objekts zu erhalten, können wir es einfach "drucken":
print(characters)Das Ergebnis:
Name Age Race
0 Frodo 50 Hobbit
1 Galadriel 8000 Elf
2 Aragorn 87 Man
Indexbeschriftungen und Indexpositionen
Wenn nicht anders angegeben, wie Sie oben sehen können, werden numerische Beschriftungen zur Identifizierung von Zeilen verwendet. Diese Bezeichnungen werden oft als "Index" bezeichnet. In solchen Fällen entsprechen sie ihren Positionen, die bei 0 beginnen. Indexbeschriftungen können jedoch zum Zeitpunkt der Initialisierung explizit über den index-Parameter definiert oder mit der rename-Methode geändert werden:
characters.rename(index={0: "r0", 1: "r1", 2: "r2"}, inplace=True)
So sieht unser DataFrame-Objekt nach dem Aufruf der obigen Methode aus (das Objekt wird an Ort und Stelle geändert, da wir inplace=True verwendet haben):
Name Age Race
r0 Frodo 50 Hobbit
r1 Galadriel 8000 Elf
r2 Aragorn 87 Man
Die Beschriftung des ersten Indexes im obigen DataFrame ist r0, aber die Position des Indexes ist 0. Wir können Zeilen und Spalten auswählen, indem wir sowohl Indexbeschriftungen als auch Indexpositionen verwenden. Um beispielsweise die erste Zeile anhand ihrer Indexbeschriftung auszuwählen, würden wir die Eigenschaft loc verwenden:
characters.loc['r0']
Um es nach Indexposition auszuwählen, verwenden wir stattdessen die Eigenschaft iloc:
characters.iloc[0]
Arbeiten mit Zeilen
Wir haben einige Beispiele dafür gesehen, wie bestimmte Zeilen anhand ihrer Indexbeschriftungen und Positionen ausgewählt werden können. Sehen wir uns nun an, wie Sie Zeilen mithilfe von Bedingungen filtern. Angenommen, wir möchten alle Zeilen relativ zu Zeichen abrufen, die älter als 50 Jahre sind. Wir müssen testen, wo der Wert der Spalte "Alter" > 50 liegt. So können wir es tun:
older_than_fifty = characters[characters['Age'] > 50]Im obigen Beispiel haben wir die Bedingung characters['Age'] > 50 verwendet: Sie wird auf das DataFrame-Objekt angewendet und gibt ein Series-Objekt zurück. In Pandas stellt ein "Series"-Objekt ein eindimensionales Array dar, das einen beliebigen Datentyp enthalten kann. In diesem Fall enthält sie boolesche Werte: True, wenn ein Wert in der Spalte "Alter" der Bedingung entspricht, andernfalls False. Hier ist die "gedruckte" Darstellung des Objekts:
0 False
1 True
2 True
Das von der Bedingung zurückgegebene Series-Objekt wird als "Filter" für das ursprüngliche DataFrame-Objekt verwendet. Es werden nur die entsprechenden Zeilen zurückgegeben:
Name Age Race
1 Galadriel 8000 Elf
2 Aragorn 87 ManMit logischen Operatoren können mehrere Bedingungen angegeben werden. Angenommen, wir möchten Zeilen auswählen, die sich auf Zeichen beziehen, die älter als 50 Jahre sind und deren Namen mit einem "A" beginnen. Wir würden schreiben:
characters[(characters['Age'] > 50) & (characters['Name'].str.startswith('A'))]
Wir haben jede Bedingung in Klammern gesetzt und einen der logischen Operatoren von Pandas (&, |, ~) verwendet, der dem Python-Operator und, oder und nicht entspricht. Im obigen Beispiel können Sie auch sehen, dass wir einen Accessor verwendet haben: str. Accessoren ermöglichen es uns, auf die Werte von Series zuzugreifen und sie mit den verfügbaren Methoden zu ändern, die sich offensichtlich je nach Datentyp ändern. Da Zeichennamen in diesem Fall durch Zeichenfolgen dargestellt werden, haben wir den str-Accessor verwendet und die startswith-Methode angewendet, die ähnlich wie die native Python-Methode mit demselben Namen funktioniert. Wie erwartet gibt das Anwenden der Bedingung das folgende Ergebnis zurück:
Name Age Race
2 Aragorn 87 Man
Hinzufügen und Ersetzen von Zeilen
Das Hinzufügen von Zeilen zu einem vorhandenen DataFrame-Objekt ist sehr einfach. Wir haben gesehen, wie man die Eigenschaften loc und iloc verwendet, um bestimmte Zeilen abzurufen, aber sie können auch zum Zuweisen von Werten verwendet werden. Um eine neue Zeile zu erstellen, müssen wir nur die neue Indexbeschriftung (oder die Indexposition, wenn wir iloc verwenden) angeben, die wir dafür verwenden möchten, und die Zeilenwerte zuweisen. Angenommen, wir möchten unserem DataFrame-Objekt ein neues Zeichen hinzufügen. Wir könnten schreiben:
characters.loc[3] = {'Name': 'Bilbo', 'Age': 110, 'Race': 'Hobbit'}
Wenn wir einen bereits vorhandenen Index verwenden, wird die vorhandene Zeile ersetzt. Um zum Beispiel die Zeile mit der Indexbeschriftung 1 (die über Galadriel) durch eine Zeile mit Informationen über den Theoden-Charakter zu ersetzen, würden wir schreiben:
characters.loc[1] = {'Name': 'Theoden', 'Age': 71, 'Race': 'Man'}
Was ist, wenn wir mehrere Zeilen gleichzeitig hinzufügen möchten? Um eine solche Aufgabe zu erfüllen, können wir ein neues DataFrame-Objekt mit den Zeilen erstellen, die wir anhängen möchten, und es dann mit der Funktion concat mit dem ursprünglichen DataFrame zusammenführen:
additional_characters = pd.DataFrame({
'Name': ['Boromir', 'Denethor', 'Elrond'],
'Age': [41, 89, 6000],
'Race': ['Man', 'Man', 'Elf']
})
all_characters = pd.concat([characters, additional_characters], ignore_index=True)
Im obigen Beispiel haben wir concat aufgerufen und die Liste der DataFrame-Objekte, die wir zusammenführen möchten, als erstes Argument übergeben. Wir haben auch angegeben, dass wir vorhandene Indexbeschriftungen nicht beibehalten möchten, indem wir das Argument ignore_index auf True festgelegt haben.
Entfernen von Zeilen
Um eine Zeile zu entfernen, können wir die drop-Methode der DataFrame-Klasse verwenden. Die Drop-Methode arbeitet mit Indexbeschriftungen, also angenommen, wir möchten die erste Zeile aus der Tabelle entfernen (Indexbeschriftung 0), würden wir Folgendes ausführen:
characters.drop(0, inplace=True)
Das erste und einzige Positionsargument, das von der Methode akzeptiert wird, kann eine einzelne Bezeichnung oder eine Liste von Indexbeschriftungen sein. Standardmäßig ändert die drop-Methode das ursprüngliche Objekt nicht an Ort und Stelle, sondern gibt ein neues Objekt zurück. Wenn wir dieses Verhalten ändern möchten, müssen wir den Parameter inplace auf True setzen, wie wir es im obigen Beispiel getan haben.
Arbeiten mit Spalten
Angenommen, wir möchten nur die Werte der Spalte "Age" aus unserem DataFrame-Objekt abrufen. Es ist ein sehr einfacher Vorgang. Alles, was wir tun müssen, ist, die Spaltenbeschriftung als Wörterbuchschlüssel zu verwenden:
ages = characters['Age']
Wenn Sie auf diese Weise auf die DataFrame-Objektspalte zugreifen, wird, wie wir bereits gesehen haben, ein Series-Objekt zurückgegeben:
0 50
1 8000
2 87
Name: Age, dtype: int64
Mehrere Spalten können gleichzeitig aus einem DataFrame-Objekt "geschnitten" werden. Zum Beispiel:
subset = characters[['Name', 'Age']]
Wenn Sie mehrere Spalten auswählen, wird ein neues DataFrame-Objekt zurückgegeben (Reihenobjekte sind eindimensional).
Hinzufügen von Spalten
Nehmen wir nun an, wir möchten unserem DataFrame-Objekt eine neue Spalte hinzufügen, um Informationen über den Wohnsitz der Zeichen zu speichern. Auch hier können wir es so machen, als ob wir einen neuen Schlüssel zu einem Wörterbuch hinzufügen würden. Hier ist, was wir schreiben würden:
characters['Residence'] = ['The Shire', 'Lothlorien', 'Minas Tirith']
Der ursprüngliche DataFrame sollte nun wie folgt aussehen:
Name Age Race Residence
0 Frodo 50 Hobbit The Shire
1 Galadriel 8000 Elf Lothlorien
2 Aragorn 87 Man Minas Tirith
Mit den oben genannten Methoden wird das DataFrame-Objekt an Ort und Stelle geändert. Wenn wir stattdessen möchten, dass das Ergebnis einem neuen Objekt zugewiesen wird, verwenden wir die Methode assign:
result = characters.assign(Residence=['The Shire', 'Lothlorien', 'Minas Tirith'])
Um eine Spalte an einer bestimmten Stelle einzufügen, können wir stattdessen die insert-Methode verwenden. Nehmen wir zum Beispiel an, wir möchten die Spalte nach der Spalte mit der Bezeichnung "Name" einfügen, die die erste ist (Position 0). Wir würden schreiben:
characters.insert(1, "Residence", ['The Shire', 'Lothlorien', 'Minas Tirith'])
Löschen von Spalten
Um eine Spalte zu löschen, können wir die gleiche Methode verwenden, die wir zum Entfernen von Zeilen verwenden. Das einzige, was wir ändern müssen, ist der Parameter axis, indem wir ihn auf 1 setzen (der Standardwert ist 0), um anzugeben, dass wir mit Spalten arbeiten möchten. Um beispielsweise die Spalte mit der Beschriftung "Name" zu entfernen, würden wir schreiben:
characters.drop("Name", axis=1, inplace=True)
Alternativ können wir den Namen der zu löschenden Spalten über den columns-Parameter angeben:
characters.drop(columns=["Name"], inplace=True)
Zugreifen auf einzelne Werte
Bisher haben wir einige Beispiele gesehen, wie man ganze Zeilen und Spalten verwalten kann. Nehmen wir stattdessen an, dass wir nur das Alter des Zeichens "Frodo" in unserem DataFrame-Objekt lesen oder ändern möchten, ohne die gesamte Zeile zu ersetzen. Um einen einzelnen Wert eines Zeilen-/Spaltenpaares (eine "Zelle" in der Terminologie der Tabellenkalkulation) abzurufen, können wir die Eigenschaft at verwenden:
frodo_age = characters.at[0, 'Age']
So weisen Sie stattdessen einen neuen Wert zu:
characters.at[0, 'Age'] = 51
Die at-Eigenschaft funktioniert, ähnlich wie loc, mit "labels", so dass das erste Argument, das wir im obigen Beispiel zwischen eckigen Klammern verwendet haben, nicht die Position des Zeilenindexes, sondern die Indexbeschriftung ist. Wenn wir mit Indexpositionen arbeiten wollen, müssen wir stattdessen iat verwenden. Da die Zeile, die sich auf "Frodo" bezieht, die erste ist (Position 0) und die Spalte "Alter" die zweite (Position 1), würden wir schreiben:
characters.iat[0, 1] = 51
Berechnungen durchführen
Die Möglichkeit, Berechnungen auf der Grundlage vorhandener Daten durchzuführen, ist von entscheidender Bedeutung. Die Pandas-Bibliothek ermöglicht es uns, solche Operationen recht einfach durchzuführen. Hier ist ein Beispiel. Angenommen, wir möchten das Durchschnittsalter der Nicht-Elfen-Zeichen in dem zuvor definierten DataFrame-Objekt "all_characters" berechnen. So könnten wir vorgehen. Zuerst wählen wir die Zeilen aus, in denen der Wert der Spalte "Race" nicht "Elf" ist: Diese Operation gibt, wie wir bereits gesehen haben, ein neues DataFrame-Objekt zurück. Wir "schneiden" die Spalte "Age" daraus ab und erhalten ein Series-Objekt, für das wir die Methode mean aufrufen:
all_characters[all_characters['Race'] != 'Elf']['Age'].mean()
Erwartungsgemäß erhalten wir als Ergebnis 66,75. Ein weiteres Beispiel. Dieses Mal wollen wir den jüngsten Nicht-Elfen-Charakter finden:
characters[characters['Race'] != 'Elf']['Age'].min()Was ist, wenn wirdas Durchschnittsalter von Charakteren basierend auf ihrer Rasse ermitteln wollen? In solchen Situationen müssen wir die groupby-Methode verwenden:
all_characters.groupby('Race')['Age'].mean()Wir erhalten folgendes Ergebnis:
Race
Elf 7000.000000
Hobbit 50.000000
Man 72.333333Dies sind nur einige grundlegende Beispiele für die Berechnungen, die wir mit den in unserem DataFrame enthaltenen Daten durchführen können!
Lesen und Schreiben von Daten aus und zu externen Quellen
In den vorherigen Beispielen haben wir DataFrame-Objekte von Grund auf neu erstellt. Meistens müssen wir jedoch Daten aus externen Quellen wie Excel-Tabellen, CSV-Dateien usw. lesen. Solche Operationen können mit dedizierten read_*- und to_*-Methoden ausgeführt werden. Sehen wir uns einige Beispiele an.
Angenommen, wir möchten ein DataFrame-Objekt aus den Daten erstellen, die in einer Microsoft Excel-Tabelle mit dem Namen "characters.xlsx" enthalten sind. Als erstes müssen wir sicherstellen, dass die openpyxl-Bibliothek installiert ist:
pip install openpyxlUm die Tabelle zu lesen und einen DataFrame zu erstellen, würden wir dann schreiben:
characters = pd.read_excel('characters.xlsx')
In ähnlicher Weise würden wir zum Importieren von Daten aus einer CSV-Datei schreiben:
characters = pd.read_csv('characters.csv')
Genauso einfach ist das Exportieren von Daten, die in einem DataFrame enthalten sind, in eine Excel-Tabelle:
characters.to_excel('characters.xlsx')
So schreiben Sie stattdessen in eine CSV-Datei:
characters.to_csv('characters.csv')
Diese Methoden akzeptieren viele Parameter, die verwendet werden können, um anzupassen, wie Daten in eine Datei geladen oder geschrieben werden. Aus offensichtlichen Gründen können wir hier nicht alle untersuchen; Weitere Informationen finden Sie in der Pandas-API-Referenz.
Erstellen von Diagrammen
Um Plots zu erstellen, wird die Bibliothek matplotlib als Backend verwendet, daher muss sie installiert werden:
pip install matplotlibStandardmäßig verwendet matplotlib das "agg"-Backend, das zum Schreiben von Plots in Dateien verwendet wird. Wenn wir erstellte Plots über eine grafische Oberfläche visualisieren möchten, müssen wir das entsprechende Backend installieren. Für dieses Beispiel verwenden wir das Qt5-Beispiel:
pip install pyqt5In Diagrammen werden nur numerische Daten angegeben. Hier erfahren Sie, wie Sie einen erstellen, um den Altersunterschied zwischen den Charakteren in unserem DataFrame zu visualisieren:
import matplotlib.pyplot as plt
all_characters.plot(x="Name")
Die Methode plot we kann sowohl auf DataFrame- als auch auf Series-Objekte angewendet werden. Im Beispiel haben wir den x-Parameter verwendet, um die Beschriftung anzugeben, die wir für die x-Achse verwenden möchten: Wir haben dies getan, um den Namen der Zeichen anstelle von numerischen Beschriftungen zu verwenden. Um den Plot zu visualisieren, rufen wir die show-Funktion auf, die vom plt-Modul bereitgestellt wird:
plt.show()
Es gibt viele Arten von Diagrammen, die erstellt werden können: Die Standardeinstellung ist die "Linie". Wir können über den kind-Parameter der plot-Methode angeben, welche wir verwenden möchten, oder eine der dedizierten Methoden direkt verwenden. In unserem Fall könnten wir, um ein vertikales Diagramm mit "Balken" zu erstellen, entweder schreiben:
all_characters.plot(x="Name", kind="bar")
Oder rufen Sie einfach an:
all_characters.plot.bar(x="Name")
Um den Plot direkt in eine Datei zu speichern, können wir die Funktion savefig des plt-Moduls aufrufen und den Dateinamen als Argument übergeben:
plt.savefig('lotr_characters_age_comparison')
Abschließende Gedanken
In diesem Tutorial haben wir die grundlegenden Konzepte hinter der Verwendung der Python-Pandas-Bibliothek kennengelernt. Wir haben gesehen, wie man tabellarische Daten erstellt und verwaltet und wie man Statistiken und Diagramme erstellt. Wir haben wirklich nur an der Oberfläche dessen gekratzt, was mit dieser fantastischen Bibliothek erreicht werden kann. Der beste Weg, es zu meistern, besteht darin, es zu verwenden und natürlich die offizielle Dokumentation zu lesen.


