In diesem Kapitel laden wir nun erstmals echte Daten. Es handelt sich dabei um einen recht überschaubaren Datensatz mit nur 5 Variablen (Spalten) und 294 Fällen (Zeilen). Pandas bietet die Möglichkeit, eine Vielzahl an unterschiedlichen Dateiformaten zu laden; in diesem Kapitel werden wir Daten aus einer CSV-Datei (.csv) sowie aus einer SPSS-Datei (.sav) einlesen.
import pandas as pd
Lesen wir zunächsten ein CSV-File ein - dieses Format ist ein durchaus übliches bei vielen Programmen bzw. kann von den meisten (oder allen?) Statistiksoftwareprodukten verarbeitet werden. Pandas bietet für den Import die Funktion read_csv() an.
read_csv() lässt sehr viele Einstellungen zu, ein Blick auf die verlinkte Seite mag sich lohnen.
daten = pd.read_csv("C:\\Datenfiles\\daten.csv")
Die Daten wurden geladen und sehen wie folgt aus (überschreitet die Anzahl der Zeilen einen bestimmten Grenzwert, so werden nur die ersten 5 sowie die letzten 5 Zeilen angezeigt):
daten
sex | age | wohnort | volksmusik | hardrock | |
---|---|---|---|---|---|
0 | 1 | 50 | 2 | 2.666667 | 3.666667 |
1 | 1 | 57 | 1 | 1.000000 | 3.333333 |
2 | 2 | 66 | 3 | 2.000000 | 4.333333 |
3 | 1 | 50 | 2 | 2.333333 | 2.666667 |
4 | 1 | 60 | 3 | 2.333333 | 3.000000 |
... | ... | ... | ... | ... | ... |
289 | 1 | 24 | 1 | 5.000000 | 2.000000 |
290 | 2 | 36 | 1 | 2.000000 | 3.666667 |
291 | 2 | 31 | 1 | 5.000000 | 4.666667 |
292 | 1 | 37 | 3 | 5.000000 | 1.000000 |
293 | 1 | 23 | 1 | 4.333333 | 3.333333 |
294 rows × 5 columns
Man kann die Einstellungen für die Ansicht von Dataframes (bspw. angezeigte Zeilen- und Spaltenanzahl) selbst einstellen.
Bringen wird aber erstmal in Erfahrung, wie viele Zeilen und Spalten aktuell angezeigt werden.
pd.options.display.max_rows
60
pd.options.display.max_columns
20
Aktuell werden also bis zu 60 Zeilen und 20 Spalten angezeigt. Im folgenden wird die Standardansicht mal auf wenige Zeilen und Spalten eingeschränkt. Umgekehrt kann sie natürlich auch erweitert werden.
pd.options.display.max_rows = 6
pd.options.display.max_rows
6
pd.options.display.max_columns = 3
pd.options.display.max_columns
3
daten
sex | ... | hardrock | |
---|---|---|---|
0 | 1 | ... | 3.666667 |
1 | 1 | ... | 3.333333 |
2 | 2 | ... | 4.333333 |
... | ... | ... | ... |
291 | 2 | ... | 4.666667 |
292 | 1 | ... | 1.000000 |
293 | 1 | ... | 3.333333 |
294 rows × 5 columns
Ändern wir die Ansicht aber nun wieder zu einem etwas sinnvollerem Umfang.
pd.options.display.max_rows = 100
pd.options.display.max_columns = 20
Längere Datensätze - wie der vorhin eingelesene - werden kaum stets zur Gänze angezeigt. Mit den Funktionen head() bzw. tail() kann man die ersten bzw. letzten 5 Zeilen (bzw. eine beliebige andere Anzahl, welche dann in der Klammer anzugeben ist: z.B. head(3), tail(12), usw.) anzeigen lassen.
daten.head()
sex | age | wohnort | volksmusik | hardrock | |
---|---|---|---|---|---|
0 | 1 | 50 | 2 | 2.666667 | 3.666667 |
1 | 1 | 57 | 1 | 1.000000 | 3.333333 |
2 | 2 | 66 | 3 | 2.000000 | 4.333333 |
3 | 1 | 50 | 2 | 2.333333 | 2.666667 |
4 | 1 | 60 | 3 | 2.333333 | 3.000000 |
daten.tail()
sex | age | wohnort | volksmusik | hardrock | |
---|---|---|---|---|---|
289 | 1 | 24 | 1 | 5.000000 | 2.000000 |
290 | 2 | 36 | 1 | 2.000000 | 3.666667 |
291 | 2 | 31 | 1 | 5.000000 | 4.666667 |
292 | 1 | 37 | 3 | 5.000000 | 1.000000 |
293 | 1 | 23 | 1 | 4.333333 | 3.333333 |
SPSS Datenfiles können mit Pandas (ab Version 0.25.0) grundsätzlich eingelesen werden (vgl. die Funktion read_spss()), jedoch liefert uns ein anderes Modul abseits von Pandas deutlich mehr Möglichkeiten für den Import von SPSS Daten. Es handelt sich dabei um das Modul pyreadstat, welches wir nun importieren.
import pyreadstat as prs
Wir laden im Folgenden die Daten in ein Dataframe (welches wir spssdaten nennen) und importieren durch die Angabe von meta gleichzeitig div. Metadaten, die sich im SPSS Datenfile befinden (Metadaten sind bspw.: Variablennamen, Variablenlabels, usw.). Der Import der Metadaten ist nötig, da ansonsten (bspw. nur mit "spssdaten = prs.read_sav('...')") nur ein Tuple und kein Dataframe importiert würde.
spssdaten, meta = prs.read_sav('C:\\Datenfiles\\daten.sav')
Das Dataframe sieht wie folgt aus (es handelt sich um den gleichen Datensatz, den wir schon vorhin aus einer CSV-Datei importiert haben).
spssdaten.head()
sex | age | wohnort | volksmusik | hardrock | |
---|---|---|---|---|---|
0 | 1.0 | 50.0 | 2.0 | 2.666667 | 3.666667 |
1 | 1.0 | 57.0 | 1.0 | 1.000000 | 3.333333 |
2 | 2.0 | 66.0 | 3.0 | 2.000000 | 4.333333 |
3 | 1.0 | 50.0 | 2.0 | 2.333333 | 2.666667 |
4 | 1.0 | 60.0 | 3.0 | 2.333333 | 3.000000 |
Nun wollen wir sehen, welche Metadaten im SPSS-Datenfile enthalten sind. Die Spaltennamen wahrscheinlich...
meta.column_names
['sex', 'age', 'wohnort', 'volksmusik', 'hardrock']
... und auch die Variablenlabels (im Gegensatz zu den meist kurzen Variablennamen in SPSS handelt es sich dabei um meist ausführlichere Bezeichnungen der Variablen). Die Variablen 4 und 5 weisen leider keine Variablenlabels auf.
meta.column_labels
['Geschlecht', 'Alter', 'Wohnumgebung', None, None]
Es gibt auch die Möglichkeit, die Variablennamen mit den dazugehörigen Variablenlabels ausgeben zu lassen.
meta.column_names_to_labels
{'sex': 'Geschlecht', 'age': 'Alter', 'wohnort': 'Wohnumgebung', 'volksmusik': None, 'hardrock': None}
Die Anzahl der Zeilen und Spalten ist auch in den Metadaten enthalten.
meta.number_rows
294
meta.number_columns
5
Ein Filelabel steht nicht zur Verfügung, die Zeichenkodierung ist UTF-8.
meta.file_label # steht offenbar keines zur Verfügung, daher wird nichts angezeigt...
meta.file_encoding
'UTF-8'
Und schließlich gibt es noch eine sehr brauchbare Information, die wir mit einem Import aus CSV-Dateien nicht hätten. In SPSS kann man den Werten bestimmte Labels zuweisen - diese sind in den importierten Metadaten enhalten und helfen uns für alle nachfolgenden Auswertungen, da wir nun wissen, was die Zahlen bedeuten. Für die Variable age waren keine Labels enthalten und werden auch nicht benötigt - es handelt sich um das Alter in Jahren. Für die Variablen volksmusik und hardrock waren ebenso keine Labels enthalten - bei beiden Variablen handelt es sich um Präferenzskalen von 1 (diese Musikrichtung höre ich sehr gerne) bis 5 (diese Musikrichtung höre ich überhaupt nicht gerne).
meta.variable_value_labels # Wertelabels anzeigen (welche in SPSS definiert wurden)
{'sex': {1.0: 'weiblich', 2.0: 'männlich'}, 'wohnort': {1.0: 'In ländlicher Umgebung', 2.0: 'In kleinstädtischer Umgebung', 3.0: 'In großstädtischer Umgebung (z.B. Graz, Wien)'}}
Auch aus der Windows Zwischenablage können Daten eingelesen werden. Z.B. könnte man in Excel einige Zeilen und Spalten markieren, diese kopieren und mit untenstehender Funktion read_clipboard() anschließend als Dataframe importieren. Untenstehende Daten wurden in einem Excel-Datenblatt eingegeben und auf dem beschriebenen Weg eingelesen. Der Zeilenindex wird dabei - wie bekannt - automatisch erstellt, d.h. aus Excel stammen nur die drei Spalten Hausnr., Hund und Katze.
data = pd.read_clipboard()
data
Hausnr. | Hund | Katze | |
---|---|---|---|
0 | 1 | Bauxi | Carlo |
1 | 2 | Rex | Miez |
2 | 3 | Bello | Pezi |
Sehen wir uns nun noch ein paar Eckdaten zum ursprünglich geladenen Dataframe daten an. Pandas bietet dafür einige Möglichkeiten an. Einen Überblick über die Spalten(Variablen)namen im Dataframe, die Datentypen, die Anzahl der Zeilen und Spalten und den Speicherplatzbedarf des Files bietet die Funktion info().
daten.info()
<class 'pandas.core.frame.DataFrame'> RangeIndex: 294 entries, 0 to 293 Data columns (total 5 columns): # Column Non-Null Count Dtype --- ------ -------------- ----- 0 sex 294 non-null int64 1 age 294 non-null int64 2 wohnort 294 non-null int64 3 volksmusik 294 non-null float64 4 hardrock 294 non-null float64 dtypes: float64(2), int64(3) memory usage: 11.6 KB
Das Attribut shape gibt die Anzahl der Zeilen und Spalten an.
daten.shape # Anzahl der Zeilen und Spalten (nur Variablen, d.h. ohne den automatisch vergebenen Index)
(294, 5)
size gibt die Anzahl an Zellen (Zeilen x Spalten) an.
daten.size # Anzahl der Elemente (Zellen) im Dataframe
1470
axes liefert Informationen über den Zeilen- und den Spaltenindex.
daten.axes
[RangeIndex(start=0, stop=294, step=1), Index(['sex', 'age', 'wohnort', 'volksmusik', 'hardrock'], dtype='object')]
Ausschließlich Informationen zum Zeilenindex liefert index.
daten.index
RangeIndex(start=0, stop=294, step=1)
Um welche Datentypen es sich bei den Variablen im Dataframe handelt, erfährt man bspw. mit dtypes.
daten.dtypes
sex int64 age int64 wohnort int64 volksmusik float64 hardrock float64 dtype: object
Die Funktion nunique() schließlich gibt für jede Spalte (Variable) an, wieviele unterschiedliche Werte darin enthalten sind. Bsp. enthält die Variable sex nur 2 unterschiedliche Werte (1 bzw. 2 für weiblich bzw. männlich), während die Variable age (Alter in Jahren) bereits 53 verschiedene Werte enthält.
daten.nunique() # Anzahl individueller (unterschiedlicher) Werte pro Spalte/Variable
sex 2 age 53 wohnort 3 volksmusik 14 hardrock 16 dtype: int64
Abschließend sei noch gezeigt, auf welchen unterschiedlichen Wegen man sich die Spalten(Variablen)namen anzeigen lassen kann.
How to get column names in Pandas dataframe
Get the list of column headers or column name in python pandas
Mit dem Attribut columns funktioniert es ganz gut.
daten.columns
Index(['sex', 'age', 'wohnort', 'volksmusik', 'hardrock'], dtype='object')
Auch die bereits bekannte Funktion head() zeigt natürlich immer die Spaltennamen an.
daten.head(0) # '0', da wir nur die Spaltennamen wollten...
sex | age | wohnort | volksmusik | hardrock |
---|
Folgende kurze for-Schleife gibt alle Spaltennamen in der Reihenfolge ihres Auftretens im Dataframe aus.
for col in daten.columns:
print(col)
sex age wohnort volksmusik hardrock
Ähnliches, wenn auch anders dargestellt, bewirkt die list() Funktion.
list(daten.columns)
['sex', 'age', 'wohnort', 'volksmusik', 'hardrock']
Das funktioniert auch ohne die Angabe von columns.
list(daten)
['sex', 'age', 'wohnort', 'volksmusik', 'hardrock']
Schließlich gibt die sorted() Funktion die Spaltennamen in alphabetischer Reihenfolge aus.
sorted(daten.columns)
['age', 'hardrock', 'sex', 'volksmusik', 'wohnort']
Wiederum funktioniert dies auch ohne die Angabe von columns.
sorted(daten)
['age', 'hardrock', 'sex', 'volksmusik', 'wohnort']