Umfragedaten vorbereiten

Survey Teil 1

Jan Kirenz

Setup

import numpy as np
import pandas as pd
from pandas.api.types import CategoricalDtype

Daten

Daten importieren

PATH = "../data/"
DATA = "raw_mr_ss24.csv"

df = pd.read_csv(PATH + DATA)

DataFrame anzeigen

df
Zeitstempel Ich bin sportlich Ich bin fleißig. Von Rückschlägen lasse ich mich nicht entmutigen. Meine Fähigkeiten und Talente sind vorgegeben und ich kann daran nicht viel ändern. 1990 lebten 58 % der Weltbevölkerung in Ländern mit niedrigem Einkommen. Wie hoch ist der Anteil heute? Geben Sie eine Zahl ein (z. B. 9, 37 oder 61) Wie viel der weltweit verbrauchten Energie stammt aus Erdgas, Kohle und Öl? Welcher Anteil der Weltbevölkerung lebt in Megacitys (Städte mit mindestens 10 Millionen Einwohnern)? Wie viele Geleebohnen befinden sich in diesem sechseckigen Glas? Wie viele Minuten verbringen Sie an einem typischen Tag in sozialen Medien (Facebook, Instagram, Snapchat, etc.)? Wie viele Minuten investieren Sie ca. pro Tag in Ihr Studium (abgesehen von Lehrveranstaltungen)? Lesen Sie zur Zeit ein Buch? Wie alt sind Sie? Sie sind ...
0 2024/04/16 10:49:54 AM OEZ trifft völlig zu trifft eher zu 2 trifft eher zu 80 ca. 82% 3 2000.0 40 3 Ja 21 Männlich
1 2024/04/16 10:50:21 AM OEZ trifft eher nicht zu trifft eher zu 2 trifft überhaupt nicht zu 23 ca. 82% 3 500.0 240 120 Ja 24 Weiblich
2 2024/04/16 10:50:22 AM OEZ teils teils trifft eher zu 4 trifft eher nicht zu 37 ca. 62% 2 756.0 240 30 Ja 19 Weiblich
3 2024/04/16 10:50:24 AM OEZ teils teils trifft eher nicht zu 3 teils teils 37 ca. 62% 3 1.0 1000 60 Nein 20 Männlich
4 2024/04/16 10:50:29 AM OEZ trifft eher zu trifft völlig zu 2 trifft eher nicht zu 65 ca. 82% 3 350.0 90 2 Ja 22 Weiblich
5 2024/04/16 10:50:29 AM OEZ trifft eher nicht zu trifft völlig zu 4 teils teils 61 ca. 62% 4 7832.0 180 40 Ja 20 Weiblich
6 2024/04/16 10:50:41 AM OEZ trifft eher zu trifft eher zu 5 trifft eher nicht zu 65 ca. 62% 2 800.0 130 30 Nein 27 Männlich
7 2024/04/16 10:50:43 AM OEZ trifft eher zu trifft eher zu 3 trifft eher nicht zu 50 ca. 82% 4 1000.0 60 120 Ja 19 Weiblich
8 2024/04/16 10:50:59 AM OEZ teils teils trifft eher zu 2 trifft überhaupt nicht zu 70 ca. 62% 3 20000.0 120 60 Ja 21 Weiblich
9 2024/04/16 10:51:11 AM OEZ trifft völlig zu teils teils 4 trifft eher nicht zu 70 ca. 82% 3 254.0 60 100 Nein 20 Männlich
10 2024/04/16 10:51:18 AM OEZ trifft eher zu trifft eher zu 3 trifft überhaupt nicht zu 40 ca. 82% 3 900.0 100 40 Nein 21 Männlich
11 2024/04/16 10:51:23 AM OEZ trifft eher nicht zu teils teils 4 trifft überhaupt nicht zu 31 ca. 82% 2 5843.0 187 60 Nein 21 Männlich
12 2024/04/16 10:51:38 AM OEZ trifft eher nicht zu trifft völlig zu 3 teils teils 65 ca. 62% 2 1152.0 240 30 Nein 20 Weiblich
13 2024/04/16 10:51:51 AM OEZ trifft eher nicht zu trifft eher zu 3 trifft eher nicht zu 9 ca. 82% 4 500.0 250 100 Ja 20 Weiblich
14 2024/04/16 10:51:55 AM OEZ trifft völlig zu trifft völlig zu 4 trifft eher zu 61 ca. 62% 3 400.0 3 2 Nein 26 Männlich
15 2024/04/16 10:52:00 AM OEZ trifft eher zu trifft völlig zu 5 trifft eher nicht zu 37 ca. 62% 3 1120.0 120 100 Ja 24 Weiblich
16 2024/04/16 10:52:01 AM OEZ trifft eher zu teils teils 4 trifft überhaupt nicht zu 64 ca. 62% 3 850.0 280 30 Nein 22 Männlich
17 2024/04/16 10:52:08 AM OEZ trifft völlig zu trifft völlig zu 4 trifft eher nicht zu 48 ca. 62% 1 260.0 5 20 Ja 20 Männlich
18 2024/04/16 10:52:08 AM OEZ trifft eher zu trifft eher zu 4 trifft eher nicht zu 65 ca. 82% 3 500.0 120 100 Ja 19 Weiblich
19 2024/04/16 10:52:14 AM OEZ trifft völlig zu teils teils 4 teils teils 61 ca. 82% 2 1500.0 100 100 Nein 20 Männlich
20 2024/04/16 10:52:15 AM OEZ trifft eher zu trifft eher nicht zu 4 trifft überhaupt nicht zu 62 ca. 82% 3 2024.0 60 90 Nein 21 Weiblich
21 2024/04/16 10:52:23 AM OEZ trifft völlig zu trifft völlig zu 3 teils teils 30 ca. 82% 4 1000.0 90 90 Ja 21 Weiblich
22 2024/04/16 10:52:27 AM OEZ trifft eher zu trifft völlig zu 2 trifft eher nicht zu 65 ca. 62% 4 350.0 90 120 Ja 22 Weiblich
23 2024/04/16 10:52:32 AM OEZ trifft völlig zu trifft eher nicht zu 3 trifft eher nicht zu 60 ca. 62% 3 1000.0 60 60 Ja 21 Weiblich
24 2024/04/16 10:52:44 AM OEZ trifft völlig zu trifft eher zu 3 trifft eher nicht zu 75 ca. 62% 2 50.0 90 2 Nein 22 Männlich
25 2024/04/16 10:52:45 AM OEZ trifft völlig zu trifft eher zu 4 teils teils 55 ca. 62% 3 87.0 120 120 Nein 22 Weiblich
26 2024/04/16 10:53:16 AM OEZ teils teils teils teils 4 trifft eher nicht zu 9 ca. 82% 3 1000.0 180 180 Nein 21 Weiblich
27 2024/04/16 10:53:35 AM OEZ trifft eher zu trifft eher zu 4 trifft eher nicht zu 48% ca. 42% 3 108.0 240 120 Nein 20 Weiblich
28 2024/04/16 10:53:38 AM OEZ trifft völlig zu teils teils 4 trifft eher nicht zu 65 ca. 82% 3 600.0 120 240 Nein 27 Männlich
29 2024/04/16 10:53:40 AM OEZ trifft eher zu teils teils 3 trifft eher nicht zu 48 ca. 62% 3 2000.0 600 120 Nein 22 Weiblich
30 2024/04/16 3:55:54 PM OEZ teils teils trifft eher zu 3 teils teils 50 ca. 62% 2 1000.0 90 90 Ja 23 Weiblich

Datentypen anzeigen

df.dtypes
Zeitstempel                                                                                                                                               object
Ich bin sportlich                                                                                                                                         object
Ich bin fleißig.                                                                                                                                          object
Von Rückschlägen lasse ich mich nicht entmutigen.                                                                                                          int64
Meine Fähigkeiten und Talente sind vorgegeben und ich kann daran nicht viel ändern.                                                                       object
1990 lebten 58 % der Weltbevölkerung in Ländern mit niedrigem Einkommen. Wie hoch ist der Anteil heute? Geben Sie eine Zahl ein (z. B. 9, 37 oder 61)     object
Wie viel der weltweit verbrauchten Energie stammt aus Erdgas, Kohle und Öl?                                                                               object
Welcher Anteil der Weltbevölkerung lebt in Megacitys (Städte mit mindestens 10 Millionen Einwohnern)?                                                      int64
Wie viele Geleebohnen befinden sich in diesem sechseckigen Glas?                                                                                         float64
Wie viele Minuten verbringen Sie an einem typischen Tag in sozialen Medien (Facebook, Instagram, Snapchat, etc.)?                                          int64
Wie viele Minuten investieren Sie ca. pro Tag in Ihr Studium (abgesehen von Lehrveranstaltungen)?                                                          int64
Lesen Sie zur Zeit ein Buch?                                                                                                                              object
Wie alt sind Sie?                                                                                                                                          int64
Sie sind ...                                                                                                                                              object
dtype: object

Info

df.info()
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 31 entries, 0 to 30
Data columns (total 14 columns):
 #   Column                                                                                                                                                 Non-Null Count  Dtype  
---  ------                                                                                                                                                 --------------  -----  
 0   Zeitstempel                                                                                                                                            31 non-null     object 
 1   Ich bin sportlich                                                                                                                                      31 non-null     object 
 2   Ich bin fleißig.                                                                                                                                       31 non-null     object 
 3   Von Rückschlägen lasse ich mich nicht entmutigen.                                                                                                      31 non-null     int64  
 4   Meine Fähigkeiten und Talente sind vorgegeben und ich kann daran nicht viel ändern.                                                                    31 non-null     object 
 5   1990 lebten 58 % der Weltbevölkerung in Ländern mit niedrigem Einkommen. Wie hoch ist der Anteil heute? Geben Sie eine Zahl ein (z. B. 9, 37 oder 61)  31 non-null     object 
 6   Wie viel der weltweit verbrauchten Energie stammt aus Erdgas, Kohle und Öl?                                                                            31 non-null     object 
 7   Welcher Anteil der Weltbevölkerung lebt in Megacitys (Städte mit mindestens 10 Millionen Einwohnern)?                                                  31 non-null     int64  
 8   Wie viele Geleebohnen befinden sich in diesem sechseckigen Glas?                                                                                       31 non-null     float64
 9   Wie viele Minuten verbringen Sie an einem typischen Tag in sozialen Medien (Facebook, Instagram, Snapchat, etc.)?                                      31 non-null     int64  
 10  Wie viele Minuten investieren Sie ca. pro Tag in Ihr Studium (abgesehen von Lehrveranstaltungen)?                                                      31 non-null     int64  
 11  Lesen Sie zur Zeit ein Buch?                                                                                                                           31 non-null     object 
 12  Wie alt sind Sie?                                                                                                                                      31 non-null     int64  
 13  Sie sind ...                                                                                                                                           31 non-null     object 
dtypes: float64(1), int64(5), object(8)
memory usage: 3.5+ KB

Daten anpassen

Spaltennamen

# Spaltennamen umbenennen
df = df.rename(columns={
    "Zeitstempel": "zeit",
    "Ich bin sportlich": "sport",
    "Ich bin fleißig.": "fleissig",
    "Von Rückschlägen lasse ich mich nicht entmutigen.": "entmutigen",
    "Meine Fähigkeiten und Talente sind vorgegeben und ich kann daran nicht viel ändern.": 'talente',
    "1990 lebten 58 % der Weltbevölkerung in Ländern mit niedrigem Einkommen. Wie hoch ist der Anteil heute? Geben Sie eine Zahl ein (z. B. 9, 37 oder 61)": "einkommen",
    "Wie viel der weltweit verbrauchten Energie stammt aus Erdgas, Kohle und Öl?": "energie",
    "Welcher Anteil der Weltbevölkerung lebt in Megacitys (Städte mit mindestens 10 Millionen Einwohnern)?": "megacity",
    "Wie viele Geleebohnen befinden sich in diesem sechseckigen Glas?": "geleebohnen",
    "Wie viele Minuten verbringen Sie an einem typischen Tag in sozialen Medien (Facebook, Instagram, Snapchat, etc.)?": "soziale_medien",
    "Wie viele Minuten investieren Sie ca. pro Tag in Ihr Studium (abgesehen von Lehrveranstaltungen)?": "studium",
    "Lesen Sie zur Zeit ein Buch?": "buch",
    "Wie alt sind Sie?": "alter",
    "Sie sind ...": "geschlecht"
}, errors="raise")

Info

df.info()
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 31 entries, 0 to 30
Data columns (total 14 columns):
 #   Column          Non-Null Count  Dtype  
---  ------          --------------  -----  
 0   zeit            31 non-null     object 
 1   sport           31 non-null     object 
 2   fleissig        31 non-null     object 
 3   entmutigen      31 non-null     int64  
 4   talente         31 non-null     object 
 5   einkommen       31 non-null     object 
 6   energie         31 non-null     object 
 7   megacity        31 non-null     int64  
 8   geleebohnen     31 non-null     float64
 9   soziale_medien  31 non-null     int64  
 10  studium         31 non-null     int64  
 11  buch            31 non-null     object 
 12  alter           31 non-null     int64  
 13  geschlecht      31 non-null     object 
dtypes: float64(1), int64(5), object(8)
memory usage: 3.5+ KB

Nominale Variablen

Liste erstellen

# Liste mit nominalen Variablen erstellen
list_nominal = ["buch", "geschlecht"]

Variablen anpassen

# Nominale Variablen als kategorial formatieren (category)
for i in list_nominal:
    df[i] = df[i].astype("category")

df[list_nominal].info()
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 31 entries, 0 to 30
Data columns (total 2 columns):
 #   Column      Non-Null Count  Dtype   
---  ------      --------------  -----   
 0   buch        31 non-null     category
 1   geschlecht  31 non-null     category
dtypes: category(2)
memory usage: 442.0 bytes

Variablen anzeigen

df[list_nominal].head()
buch geschlecht
0 Ja Männlich
1 Ja Weiblich
2 Ja Weiblich
3 Nein Männlich
4 Ja Weiblich
  • Beide nominalen Variablen enthalten Text in den Zeilen (mit jeweils zwei möglichen Ausprägungen).

  • Dies kann bei späteren Analysen zu Problemen führen, weshalb wir zusätzlich so genannte “Dummy-Variablen” erzeugen, die nur die Werte 1 und 0 enthalten.

Dummy Variablen erstellen

dummy_nominal = pd.get_dummies(
    df[list_nominal],  prefix_sep='__').astype('category')

dummy_nominal
buch__Ja buch__Nein geschlecht__Männlich geschlecht__Weiblich
0 True False True False
1 True False False True
2 True False False True
3 False True True False
4 True False False True
5 True False False True
6 False True True False
7 True False False True
8 True False False True
9 False True True False
10 False True True False
11 False True True False
12 False True False True
13 True False False True
14 False True True False
15 True False False True
16 False True True False
17 True False True False
18 True False False True
19 False True True False
20 False True False True
21 True False False True
22 True False False True
23 True False False True
24 False True True False
25 False True False True
26 False True False True
27 False True False True
28 False True True False
29 False True False True
30 True False False True

Dummy Variablen zu Daten hinzufügen

# Dummy-Variablen hinzufügen
df = df.join(dummy_nominal)

df.head()
zeit sport fleissig entmutigen talente einkommen energie megacity geleebohnen soziale_medien studium buch alter geschlecht buch__Ja buch__Nein geschlecht__Männlich geschlecht__Weiblich
0 2024/04/16 10:49:54 AM OEZ trifft völlig zu trifft eher zu 2 trifft eher zu 80 ca. 82% 3 2000.0 40 3 Ja 21 Männlich True False True False
1 2024/04/16 10:50:21 AM OEZ trifft eher nicht zu trifft eher zu 2 trifft überhaupt nicht zu 23 ca. 82% 3 500.0 240 120 Ja 24 Weiblich True False False True
2 2024/04/16 10:50:22 AM OEZ teils teils trifft eher zu 4 trifft eher nicht zu 37 ca. 62% 2 756.0 240 30 Ja 19 Weiblich True False False True
3 2024/04/16 10:50:24 AM OEZ teils teils trifft eher nicht zu 3 teils teils 37 ca. 62% 3 1.0 1000 60 Nein 20 Männlich False True True False
4 2024/04/16 10:50:29 AM OEZ trifft eher zu trifft völlig zu 2 trifft eher nicht zu 65 ca. 82% 3 350.0 90 2 Ja 22 Weiblich True False False True

Liste um Dummy Variablen ergänzen

# Liste um die neuen Variablen erweitern
dummy_nominal_name = dummy_nominal.columns.tolist()

list_nominal.extend(dummy_nominal_name)
list_nominal
['buch',
 'geschlecht',
 'buch__Ja',
 'buch__Nein',
 'geschlecht__Männlich',
 'geschlecht__Weiblich']

Likert-Skala, Ordinal und Quasi-Metrisch

Variablen

  • Die Variablen sport,fleissig, talente und entmutigen wurden mit Hilfe einer so genannten Likert-Skala erhoben.

  • Die Antwortmöglichkeiten reichen bei der Likertskala typischerweise von „trifft überhaupt nicht zu“ bis “trifft völlig zu“

  • Eine gerade Zahl der Antwortmöglichkeiten ist ebenso gebräuchlich wie eine ungerade Anzahl.

Antwortmöglichkeiten

  • Es ist jedoch sinnvoll, in einem Fragebogen nur eine der beiden Varianten zu verwenden.

  • Zudem sollte die Reihenfolge der Antwortmöglichkeiten immer identisch sein.

  • Eine ungerade Anzahl wird verwendet, wenn eine mittlere Ausprägung (bspw. “teils teils”) sinnvoll ist.

  • Eine gerade Anzahl zwingt dagegen zur Entscheidung zu einer Seite (tendenzielle Zustimmung oder Ablehnung).

Ordinal vs quasi-metrisch

  • Da wir nicht davon ausgehen können, dass eine befragte Person die Abstände der einzelnen Antwortmöglichkeiten als gleich weit entfernt wahrnimmt (äquidistant), handelt es sich streng genommen um ein ordinales Skalenniveau.

  • Um bei der späteren Auswertung die erhobenen Daten aber dennoch wie intervallskalierte Daten behandeln zu können, behandelt man die Variablen oftmals als “quais-metrisch” und unterstellt somit (zumindest annäherungsweise) äquidistante Abstände.

Ordinal vs quasimetrisch

  • Wir behandeln in Folgenden zwei unterschiedliche Optionen zum Umgang mit den Variablen:

    • Option 1: Wir behandeln die Variablen als ordinale Variablen (wird im Anschluss gezeigt).

    • Option 2: Wir behandeln die Variablen als “quasimetrische” Variablen - d.h. wie numerische Daten (diese Option wird in dem Abschnitt “Quasi-metrische Variablen” behandelt).

Skalierung der Variablen anpassen

Text vs. numerische Werte

  • In den Fragen wurde “sport”, “fleissig”, “talente” mit Hilfe von Text-Bezeichnungen wie “trifft überhaupt nicht zu” erhoben

  • entmutigen” wurde mit Hilfe von numerischen Werten (1 bis 5) erfasst.

  • Da wir besser mit einheitlich skalierten Werten umgehen können, wird zunächst die Variable “entmutigen” in das gleiche Format überführt.

Variable im Original speichern

  • Da wir die Variable entmutigen nicht versehentlich durch Datentransformationen fehlerhaft verändern möchten, speichern wir sie zunächst nochmals in der originalen Version ab (als entmutigen_orig).
df['entmutigen_orig'] = df['entmutigen']

Liste für Anpassung erzeugen

  • Erzeugung der Listen für die Veränderung der Variable (in der korrekten Reihenfolge):
werte = [1, 2, 3, 4, 5]

likert = ["trifft überhaupt nicht zu",
          "trifft eher nicht zu",
          "teils teils",
          "trifft eher zu",
          "trifft völlig zu"]

Variable anpassen

df['entmutigen'].replace(werte, likert, inplace=True)

df['entmutigen'].head()
0    trifft eher nicht zu
1    trifft eher nicht zu
2          trifft eher zu
3             teils teils
4    trifft eher nicht zu
Name: entmutigen, dtype: object
df['entmutigen_orig'].head()
0    2
1    2
2    4
3    3
4    2
Name: entmutigen_orig, dtype: int64

Ordinale Variablen

Liste erstellen

  • Erstellung einer Liste:
list_ordinal = ["sport", "fleissig", "talente", "entmutigen"]

Verwendung von pandas CategoricalDtype

cat_type = CategoricalDtype(categories=likert, ordered=True)

cat_type
CategoricalDtype(categories=['trifft überhaupt nicht zu', 'trifft eher nicht zu',
                  'teils teils', 'trifft eher zu', 'trifft völlig zu'],
, ordered=True, categories_dtype=object)

Ordinale Variablen anpassen

df[list_ordinal] = df[list_ordinal].astype(cat_type)
df["sport"]
0         trifft völlig zu
1     trifft eher nicht zu
2              teils teils
3              teils teils
4           trifft eher zu
5     trifft eher nicht zu
6           trifft eher zu
7           trifft eher zu
8              teils teils
9         trifft völlig zu
10          trifft eher zu
11    trifft eher nicht zu
12    trifft eher nicht zu
13    trifft eher nicht zu
14        trifft völlig zu
15          trifft eher zu
16          trifft eher zu
17        trifft völlig zu
18          trifft eher zu
19        trifft völlig zu
20          trifft eher zu
21        trifft völlig zu
22          trifft eher zu
23        trifft völlig zu
24        trifft völlig zu
25        trifft völlig zu
26             teils teils
27          trifft eher zu
28        trifft völlig zu
29          trifft eher zu
30             teils teils
Name: sport, dtype: category
Categories (5, object): ['trifft überhaupt nicht zu' < 'trifft eher nicht zu' < 'teils teils' < 'trifft eher zu' < 'trifft völlig zu']
# Anzeige der Ausprägungen
df['sport'].cat.categories
Index(['trifft überhaupt nicht zu', 'trifft eher nicht zu', 'teils teils',
       'trifft eher zu', 'trifft völlig zu'],
      dtype='object')

Liste der kategorialen Variablen erstellen

list_cat = list_nominal + list_ordinal

Numerische Variablen

Übersicht

  • Wir behandeln zunächst die “eindeutig” numerischen Variablen (d.h. wir ignorieren die quasi-metrischen). diese wären:

  • einkommen

  • energie

  • megacity

  • geleebohnen

  • soziale_medien

  • studium

  • alter

Liste erstellen

list_num = ['einkommen', 'energie', 'megacity', 'geleebohnen',
            'soziale_medien', 'studium', 'alter']

df[list_num].info()
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 31 entries, 0 to 30
Data columns (total 7 columns):
 #   Column          Non-Null Count  Dtype  
---  ------          --------------  -----  
 0   einkommen       31 non-null     object 
 1   energie         31 non-null     object 
 2   megacity        31 non-null     int64  
 3   geleebohnen     31 non-null     float64
 4   soziale_medien  31 non-null     int64  
 5   studium         31 non-null     int64  
 6   alter           31 non-null     int64  
dtypes: float64(1), int64(4), object(2)
memory usage: 1.8+ KB

Erkenntnisse

  • Wir können mit df.info() erkennen, dass abgesehen von energie bereits alle Variablen korrrekt als “int64” vorliegen

  • Siehe zur Bedeutung von Int64 diesen Stackoverflow-Beitrag)

Untersuchung von Problemen

df['energie'].head()
0    ca. 82%
1    ca. 82%
2    ca. 62%
3    ca. 62%
4    ca. 82%
Name: energie, dtype: object
  • In den Antwortmöglichkeiten der Variable waren neben numerischen Werten auch Buchstaben und ein Sonderzeichen enthalen: “ca.” und “%”.

  • Damit wir sinnvoll mit der Variable arbeiten können, müssen diese entfernt werden.

Variable im Original speichern

  • Da wir die Variable nicht versehentlich durch Datentransformationen korrumpieren möchten, speichern wir sie zunächst nochmals in der originalen Version ab (als energie_orig).

  • Um die numerischen Werte leichter extrahieren zu können, nutzen wir das Format “String”.

df['energie_orig'] = df['energie'].astype("string")

Regular Expressions

  • Im nächsten Schritt nutzen wir einen regulärer Ausdruck (englisch regular expression, Abkürzung RegExp oder Regex) um die Zahl aus dem String zu extrahieren.
Ausdruck Bedeutung Beschreibung
digit eine Ziffer, also [0-9] (und evtl. auch weitere Zahlzeichen in Unicode, z. B. bengalische Ziffern)
no digit ein Zeichen, das keine Ziffer ist, also [^\d]
word character ein Buchstabe, eine Ziffer oder der Unterstrich, also [a-zA-Z_0-9] (und evtl. auch nicht-lateinische Buchstaben, z. B. Umlaute)
no word character ein Zeichen, das weder Buchstabe noch Zahl noch Unterstrich ist, also [^\w]
whitespace meist zumindest das Leerzeichen und die Klasse der Steuerzeichen  ,  und 
no whitespace ein Zeichen, das kein Whitespace ist, also [^\s]

Anpassung der Variable

  • Falls mehr als ein einzelnes Zeichen extrahiert werden soll, muss am Ende des Ausdrucks ein + hinzugefügt werden.

  • Wir nutzen regular expressions und überschreiben die alte Variable energie mit dem neuen Eintrag.

  • Zudem speichern wir sie als integer.

Anpassung der Variable

df['energie'] = df['energie_orig'].str.extract('(\d+)').astype(int)
df[['energie_orig', 'energie']].head()
energie_orig energie
0 ca. 82% 82
1 ca. 82% 82
2 ca. 62% 62
3 ca. 62% 62
4 ca. 82% 82

Quasi-metrische Variablen

Kontext

  • Variablen sport,fleissig, und talente wurden mit Hilfe einer Likert-Skala erhoben und könnten somit auch als “quasi-metrisch” behandelt werden (anstelle von ordinal).

  • Dabei muss jedoch beachtet werden, dass bspw. der Mittelwert aufgrund der Art der Messung (insbesondere wenn eine neutrale mittlere Ausprägung verwendet wird) an Aussagekraft verlieren.

Originaldaten sichern

  • Damit wir die Originaldaten nicht “verlieren”, erzeugen wir neue Variablen.

  • Dafür kopieren wir die Daten und fügen diesen die Endung “qm” (für quasimetrisch) hinzu.

for i in list_ordinal:
    df[i + "_qm"] = df[i]

Liste erzeugen

# Erstellung der Liste mit Hilfe von filter und regular expressions
list_qm = df.filter(regex='_qm').columns.to_list()
list_qm
['sport_qm', 'fleissig_qm', 'talente_qm', 'entmutigen_qm']

Info

df[list_qm].info()
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 31 entries, 0 to 30
Data columns (total 4 columns):
 #   Column         Non-Null Count  Dtype   
---  ------         --------------  -----   
 0   sport_qm       31 non-null     category
 1   fleissig_qm    31 non-null     category
 2   talente_qm     31 non-null     category
 3   entmutigen_qm  31 non-null     category
dtypes: category(4)
memory usage: 1.1 KB

Skalierung anpassen

  • Wir nutzen nun ein ähnliches Vorgehen wie bei der Anpassung der Variable “entmutigen”
for i in list_qm:
    df[i].replace(likert, werte, inplace=True)
    df[i] = df[i].astype("int")

Daten anzeigen

df[list_qm].head()
sport_qm fleissig_qm talente_qm entmutigen_qm
0 5 4 4 2
1 2 4 1 2
2 3 4 2 4
3 3 2 3 3
4 4 5 2 2
df[list_qm].info()
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 31 entries, 0 to 30
Data columns (total 4 columns):
 #   Column         Non-Null Count  Dtype
---  ------         --------------  -----
 0   sport_qm       31 non-null     int64
 1   fleissig_qm    31 non-null     int64
 2   talente_qm     31 non-null     int64
 3   entmutigen_qm  31 non-null     int64
dtypes: int64(4)
memory usage: 1.1 KB

Liste für metrische Variablen

list_metric = list_num + list_qm

Daten speichern

Daten als CSV speichern

Speichern als CSV:

PATH = "../data/"
FILE = "clean_data"
FORMAT_CSV = ".csv"
df.to_csv(PATH + FILE + FORMAT_CSV, index=False)

Daten als Excel speichern

Speichern als Excel-Datei:

#FORMAT_EXCEL = ".xlsx"

#df.to_excel(PATH + FILE + FORMAT_EXCEL, index=False)