Zu Beginn wird - wie in allen folgenden Kapiteln auch - das Paket Pandas importiert, und zwar mit der Abkürzung pd, so dass bei jeglicher weiteren Verwendung des Pakets nur mehr pd geschrieben werden muss, der Schreibaufwand also minimiert wird. pd ist dabei die international übliche Abkürzung für das Importieren von Pandas in der Python Community und sollte einheitlich auch in eigenen Scripts oder Programmen so verwendet werden.
import pandas as pd
Bevor in Kapitel 4 echte Daten aus bereits vorhandenen Datenfiles geladen bzw. importiert werden, sehen wir uns im Folgenden einige Möglichkeiten an, wie man direkt in Python Variablen und dazugehörige Werte eingibt und daraus ein Dataframe (eine zweidimensionale tabellarische Datenstruktur; also Zeilen und Spalten - wie man es bspw. von Excel oder SPSS kennt) erstellt.
Different ways to create Pandas Dataframe
Im Folgenden werden 4 (teils recht ähnliche) Möglichkeiten präsentiert, ein Dataframe zu erstellen (es gibt auch noch weitere Möglichkeiten, als die 4 angeführten).
Zuerst wird dem Objekt daten1 ein Dictionary mit Markennamen sowie Preisen zugewiesen, danach wird mit der Funktion pd.DataFrame() das Dataframe df1 (df ist eine häufig verwendete Abkürzung für Dataframe) erstellt, indem ihm das Objekt daten1 zugewiesen wird und als Spalten(Variablen)namen Marke und Preis übergeben werden.
daten1 = {'Marke' : ['Nike','Puma','Adidas','Lacoste'], 'Preis' : [35, 30, 30, 45]}
df1 = pd.DataFrame(daten1 ,columns = ['Marke', 'Preis'])
Durch Eingabe des Dataframenamens df1 erhält man bereits den Output - die tabellarische Darstellung des Dataframeinhalts. Der Zeilenindex ganz links wird übrigens von Pandas automatisch erstellt (und wird nicht zu den Spalten gezählt - das Dataframe enthält somit 2 Spalten (unsere beiden Variablen Marke und Preis)).
df1
Marke | Preis | |
---|---|---|
0 | Nike | 35 |
1 | Puma | 30 |
2 | Adidas | 30 |
3 | Lacoste | 45 |
Wie voriges Beispiel, jedoch ohne gesonderte Angabe der Spaltennamen (ist auch nicht nötig, wenn man alle im Dictionary enthaltenen Spalten übernehmen will. Möchte man nicht alle Spalten ins Dataframe übernehmen, so könnte man in diesem Beispiel auch nur columns=['Fisch'] angeben, Länge würde dann nicht im Dataframe enthalten sein).
daten2 = {'Fisch' : ['Karpfen', 'Hecht', 'Forelle', 'Wels'], 'Länge' : [55, 70, 40, 90]}
df2 = pd.DataFrame(daten2)
Und hier der Output nach Eingabe von df2, dem Namen des Dataframes aus Bsp. 2.
df2
Fisch | Länge | |
---|---|---|
0 | Karpfen | 55 |
1 | Hecht | 70 |
2 | Forelle | 40 |
3 | Wels | 90 |
Die Erstellung des Dictionarys mit den Spaltennamen und dazugehörigen Werten unterscheidet sich nicht von Bsp. 1 bzw. 2. Jedoch wird nun im Rahmen der Erstellung des Dataframes (zweite Codezeile) ein eigener Index (anstelle des wie in Bsp. 1 und 2 automatisch von Pandas vergebenen Index) zugewiesen. Ein solcher Index könnte bspw. auch die Fragebogennummer bzw. lfd. Nummer sein (dies sollte man, bspw. falls Daten später kontrolliert bzw. nachgeprüft werden, immer in Datenfiles haben!).
daten3 = {'Stadt' : ['Wien', 'Graz', 'Salzburg', 'Fürstenfeld'], 'Einwohner' : [1800000, 280000, 160000, 5000]}
df3 = pd.DataFrame(daten3, index = ['Rang 1', 'Rang 2', 'Rang 3', 'Rang 4'])
Die Outputtabelle enthält nun den selbst vergebenen Index und nicht einen automatisch von Pandas vergebenen.
df3
Stadt | Einwohner | |
---|---|---|
Rang 1 | Wien | 1800000 |
Rang 2 | Graz | 280000 |
Rang 3 | Salzburg | 160000 |
Rang 4 | Fürstenfeld | 5000 |
Das letzte Beispiel geht nun bei der Eingabe der Spaltennamen und der Werte einen anderen Weg als die drei vorhergehenden Beispiele. Nun werden dem Objekt daten4 zuerst ausschließlich die Werte für die beiden Spalten in Form einer Liste übergeben. Im Zuge der Erstellung des Dataframes werden schließlich die beiden Spaltennamen übergeben.
daten4 = [['Fred', 180], ['Susi', 165], ['Max', 190], ['Andrea', 175]]
df4 = pd.DataFrame(daten4, columns = ['Name', 'Größe'])
Für den Output spielt dies alles keine Rolle. Abgesehen vom Inhalt ändert sich bei allen vier gezeigten Beispielen nichts am Aufbau oder der Funktionalität der Tabelle.
df4
Name | Größe | |
---|---|---|
0 | Fred | 180 |
1 | Susi | 165 |
2 | Max | 190 |
3 | Andrea | 175 |
Um div. Analysen bzw. Vorgehensweisen mit umfangreicherem Datenmaterial zu simulieren bzw. zu testen, bietet es sich an, die Daten nicht wie vorhin selbst einzutippen, sondern eine beliebige Anzahl von Daten automatisch erstellen zu lassen. Zu diesem Zweck wird vorab das Paket numpy mit der Abkürzung np importiert.
import numpy as np
Nun werden zwei Zahlenreihen mit jeweils 5 Zahlen erstellt und den beiden Objekten a bzw. b zugewiesen. Das Modul random im Paket numpy enhält die Funktion randn(), welche normalverteilte (Mittelwert = 0, Standardabweichung = 1) Zufallszahlen generiert.
a, b = np.random.randn(5), np.random.randn(5)
Jetzt wird ein Dataframe gebildet und anschließend aufgerufen, welches aber noch leer ist...
daten = pd.DataFrame()
daten # noch sind aber keine Daten enthalten
Vorhin erstellte Objekte a und b werden dem Dataframe nun als Spalten hinzugefügt und mit 'a' bzw. 'b' bezeichnet. Das Dataframe ist nun fertig, d.h. enthält die Spalten und alle Werte.
daten ['a'] = a
daten ['b'] = b
daten # nun sind die vorhin erstellten Zahlen enthalten
a | b | |
---|---|---|
0 | -0.584532 | 1.834036 |
1 | -0.445541 | 1.112410 |
2 | -1.731362 | 0.103345 |
3 | 0.754921 | 0.492159 |
4 | 1.253666 | -0.834235 |
Die Erstellung des Dataframes, die Bennenung der Spalten sowie die Generierung der Zufallszahlen für beide Spalten können auch leicht in einer einzigen Codezeile eingegeben werden
df = pd.DataFrame({'A' : np.random.randn(3), 'B' : np.random.randn(3)})
Hier das erstellte Dataframe:
df
A | B | |
---|---|---|
0 | 1.298208 | 2.093076 |
1 | -1.386325 | 1.412125 |
2 | 0.500713 | 1.323926 |
Diagramme und Korrelationsanalysen sind zwar erst Thema späterer Kapitel (und werden dort erklärt), jedoch bietet es sich an dieser Stelle an, die normalverteilten Zufallszahlen genauer zu betrachten, d.h. die beiden Variablen miteinander abzubilden. Da es sich um zwei normalverteilte Zufallsvariablen handelt, wird die Korrelation zwischen beiden Variablen zumeist eher gering sein. Mit zunehmender Fallzahl wird sie immer öfter nahe bei Null liegen.
ax = daten.plot.scatter(x = 'a', y = 'b', c = 'green')
# x und y bezeichnen die Variablen, c bezeichnet die Farbe der Punkte im Streudiagramm
print("\nKorrelationskoeffizient nach Pearson")
daten.corr(method = 'pearson').round(3)
Korrelationskoeffizient nach Pearson
a | b | |
---|---|---|
a | 1.000 | -0.422 |
b | -0.422 | 1.000 |
Ein Dataframe sollte - sofern man es zu einem späteren Zeitpunkt wieder verwenden möchte - natürlich auch gespeichert werden. Nachfolgend wurde rund um die Funktion to_csv() eine einfache Funktion geschrieben, die einerseits nachfragt, ob gespeichert werden soll oder nicht und andererseits auch die Eingabe eines Dateinamens erlaubt. Gespeichert wird die Datei dann im CSV-Format, d.h. als Datei, in denen die einzelnen Spalten durch ein Komma getrennt sind.
How to Export Pandas DataFrame to a CSV File
Saving a pandas Dataframe as a CSV File
Saving a Pandas Dataframe as a CSV
How to avoid Python/Pandas creating an index in a saved csv?
Durch die Angabe von index=False wird vermieden, dass bei jedem Speichervorgang ein neuer (zusätzlicher) Zeilenindex eingefügt wird!
def save(df):
speichern = input("Dataframe \n\n{}\n\n als CSV File speichern? j/n ".format(df.head(3)))
if speichern == "j":
file = input("\n Filename: ")
df.to_csv("C:\\Datenfiles\\{}.csv".format(file), index = False) # 'index = False' ist relevant!
print('File {} wurde gespeichert'.format(file))
elif speichern == "n":
print("\n Ok, nicht speichern...")
else:
print("\n Ungültige Eingabe!")
save(df)
# Speichern des neuen Dataframes - kann auch als eigenes Modul ausgelagert und erweitert (z.B. um Pfadangabe usw.) werden
Wird die Funktion mit save(df) ('df' steht für den Namen des zu speichernden Dataframes) aufgerufen, wird auch noch eine dreizeilige Ansicht des zu speichernden Dataframes angezeigt. Somit kann man nochmals kurz prüfen, ob man das richtige Dataframe speichert.
save(daten) # 'daten' = Name des zu speichernden Dataframes!
Dataframe a b 0 -0.584532 1.834036 1 -0.445541 1.112410 2 -1.731362 0.103345 als CSV File speichern? j/n n Ok, nicht speichern...
Dabei wird das Dataframe nicht mehr angezeigt und auch nicht nachgefragt, ob man wirklich speichern möchte.
daten.to_csv("C:\\Datenfiles\\testversion.csv", index = False)
# 'daten' steht für den Namen des zu speichernden Dataframes
Mit der Funktion to_clipboard() können beliebige Ausschnitte eines Dataframes (oder auch das ganze Dataframe) in die Windows Zwischenablage kopiert und danach in anderen Programmen (z.B. Excel, Word, usw.) eingefügt und weiterverwendet werden.
daten.head(3).round(2).to_clipboard() # kopiert die Outputtabelle in die Windows Zwischenablage
# (allerdings mit . als Dezimaltrennzeichen, somit Probleme bspw. beim Einfügen in Excel weil Kommazahlen nicht erkannt!)
# nachfolgend abgebildete Tabelle ist nur ein Symbolbild
a | b | |
---|---|---|
0 | -0.39 | 1.22 |
1 | 2.19 | 2.17 |
2 | -2.66 | -1.44 |
Man kann das aktuelle Arbeitsverzeichnis - also jenes Verzeichnis, aus dem Files geladen werden bzw. in dem Files gespeichert werden sofern man keinen anderen Pfad angibt - identifizieren. Dazu muss zuerst das Modul os importiert werden. In diesem Modul befindet sich die Funktion getcwd(), welche wir aufrufen, um das aktuelle Arbeitsverzeichnis in Erfahrung zu bringen.
import os
os.getcwd() # Aktuelles Arbeitsverzeichnis
'C:\\'
Zum Ändern des Arbeitsverzeichnisses (für die aktuelle Sitzung, also nicht dauerhaft für alle Zeiten...) gibt es die Funktion chdir(), welcher man den Pfad zum gewünschten neuen Arbeitsverzeichnis übergeben kann. In untenstehender Funktion wird zuerst zudem noch geprüft, ob das gewünschte neue Arbeitsverzeichnis überhaupt existiert (d.h. angelegt ist).
if os.path.exists("C:\\"):
os.chdir("C:\\Datenfiles") # Dies soll das neue Arbeitsverzeichnis sein, sofern es existiert
print("Arbeitsverzeichnis wurde geändert")
else:
print("Änderung nicht möglich, ev. existiert der Ordner nicht...")
Arbeitsverzeichnis wurde geändert
Ein erneuter Aufruf von getcwd() bestätigt, dass das Arbeitsverzeichnis wunschgemäß geändert wurde.
os.getcwd()
'C:\\Datenfiles'