2  Operationen

Pandas erlaubt wie NumPy vektorisierte Operationen, dass heißt, Berechnungen mit einer Series oder einem DataFrame werden auf jedes Element angewendet. So können die Rechenoperatoren direkt verwendet werden.

print("Temperaturen in Celsius:")
print(27 * "=")
print(temperaturen, "\n")

print("Temperaturen in Fahrenheit:")
print(27 * "=")
print(temperaturen  * 9/5 + 32)
Temperaturen in Celsius:
===========================
     2021  2022  2023  2024
Jan     2     3    -3    -1
Feb     4     6    -1     2
Mär     7     9     4     5
Apr    12    13     9     8
Mai    19    18    15    17
Jun    23    21    20    24
Jul    25    24    20    25
Aug    23    23    19    20
Sep    18    19    16    17
Okt    15    14    15    14
Nov     9     8     7     9
Dez     5     4     6     2 

Temperaturen in Fahrenheit:
===========================
     2021  2022  2023  2024
Jan  35.6  37.4  26.6  30.2
Feb  39.2  42.8  30.2  35.6
Mär  44.6  48.2  39.2  41.0
Apr  53.6  55.4  48.2  46.4
Mai  66.2  64.4  59.0  62.6
Jun  73.4  69.8  68.0  75.2
Jul  77.0  75.2  68.0  77.0
Aug  73.4  73.4  66.2  68.0
Sep  64.4  66.2  60.8  62.6
Okt  59.0  57.2  59.0  57.2
Nov  48.2  46.4  44.6  48.2
Dez  41.0  39.2  42.8  35.6

Auch boolsche Operationen können direkt ausgeführt werden.

print("Minusgrade:")
print(27 * "=")
print(temperaturen  < 0)
Minusgrade:
===========================
      2021   2022   2023   2024
Jan  False  False   True   True
Feb  False  False   True  False
Mär  False  False  False  False
Apr  False  False  False  False
Mai  False  False  False  False
Jun  False  False  False  False
Jul  False  False  False  False
Aug  False  False  False  False
Sep  False  False  False  False
Okt  False  False  False  False
Nov  False  False  False  False
Dez  False  False  False  False

2.1 Zeilen- und spaltenweise Operationen

Pandas umfasst eine Vielzahl von Methoden, die arithmetische, summarische, boolsche und Indexfunktionen umsetzen. Eine vollständige Übersicht finden Sie hier: https://pandas.pydata.org/docs/reference/index.html.

In der Regel werden die Funktionen standardmäßig spaltenweise angewendet. Mit dem Argument axis = 1 wird die jeweilige Funktion zeilenweise ausgeführt. Die Funktionen sind auch für Series verfügbar.

Im Folgenden werden einige Methoden exemplarisch vorgestellt.

arithmetische Funktionen

Die Methoden pd.DataFrame.add(), pd.DataFrame.sub(), pd.DataFrame.mul(), pd.DataFrame.div(), pd.DataFrame.floordiv(), pd.DataFrame.mod() und pd.DataFrame.pow() entsprechen den Grundrechenarten mit den Operatoren +, -, *, /, //, %, **. Sie eignen sich gut für verkettete Operationen.

print("Temperaturen in Fahrenheit:")
print(27 * "=")
print(temperaturen.mul(9).div(5).add(32))
Temperaturen in Fahrenheit:
===========================
     2021  2022  2023  2024
Jan  35.6  37.4  26.6  30.2
Feb  39.2  42.8  30.2  35.6
Mär  44.6  48.2  39.2  41.0
Apr  53.6  55.4  48.2  46.4
Mai  66.2  64.4  59.0  62.6
Jun  73.4  69.8  68.0  75.2
Jul  77.0  75.2  68.0  77.0
Aug  73.4  73.4  66.2  68.0
Sep  64.4  66.2  60.8  62.6
Okt  59.0  57.2  59.0  57.2
Nov  48.2  46.4  44.6  48.2
Dez  41.0  39.2  42.8  35.6

Außerdem kann mit dem Parameter fill_value ein Füllwert für fehlende Werte spezifiziert werden (dieser wird vor der Operation eingesetzt). Wie NumPys np.nan umfasst auch Pandas einen speziellen fehlenden Wert: pd.NA (achten Sie auf den Datentyp der Ausgabe). Der Umgang mit fehlenden Werten wird ausführlich im Methodenbaustein Einlesen strukturierter Datensätze behandelt.

missing_value = pd.Series([1, pd.NA, 3])
print(missing_value.add(1, fill_value = -999), "\n")
print(missing_value.add(1, fill_value = np.nan), "\n")
print(missing_value.add(1, fill_value = pd.NA))
0      2
1   -998
2      4
dtype: int64 

0    2.0
1    NaN
2    4.0
dtype: float64 

0       2
1    <NA>
2       4
dtype: object

summarische Funktionen

  • pd.DataFrame.mean() ermittelt den Durchschnitt.
  • pd.DataFrame.median() ermittelt den Median.
  • pd.DataFrame.mode() ermittelt den Modus.
  • pd.DataFrame.sum() ermittelt die Summe.
  • pd.DataFrame.cumsum() ermittelt die kummulierte Summe.
  • pd.DataFrame.min() und pd.DataFrame.max() ermitteln Minimum bzw. Maximum.
  • pd.DataFrame.cummin() und pd.DataFrame.cummax() ermittelt das kummulierte Minimum bzw. Maximum.
# spaltenweise
print("Mittlere Jahrestemperaturen")
print(27 * "=")
print(temperaturen.mean(), "\n")

# zeilenweise
print("Monatliche Mindesttemperatur")
print(28 * "=")
print(temperaturen.min(axis = 1))
Mittlere Jahrestemperaturen
===========================
2021    13.500000
2022    13.500000
2023    10.583333
2024    11.833333
dtype: float64 

Monatliche Mindesttemperatur
============================
Jan    -3
Feb    -1
Mär     4
Apr     8
Mai    15
Jun    20
Jul    20
Aug    19
Sep    16
Okt    14
Nov     7
Dez     2
dtype: int64

boolsche Funktionen

Pandas bietet wie die Pythonbasis verschiedene boolsche Funktionen.

pd.DataFrame.isin(values) prüft für jedes Element des DataFrame, ob dieses in values enthalten ist. Mit dem Operator ~ kann geprüft werden, ob die Elemente eines DataFrame nicht in values enthalten sind: ~pd.DataFrame.isin(values).
Die Funktionsausführung ist abhängig vom Datentyp des in values übergebenen Objekts.

  • Wenn values eine Liste oder ein NumPy-Array ist, ist das Ergebnis True, wenn es eine Übereinstimmung mit einem der enthaltenen Elemente gibt.
  • Ist value eine Series oder ein DataFrame, wird die Übereinstimmung positionsbasiert überprüft (siehe Beispiel).

Für Einzelwerte oder eine Liste wird die Übereinstimmung elementweise überprüft.

print(temperaturen, "\n")

print(temperaturen.isin([2, 3]))
     2021  2022  2023  2024
Jan     2     3    -3    -1
Feb     4     6    -1     2
Mär     7     9     4     5
Apr    12    13     9     8
Mai    19    18    15    17
Jun    23    21    20    24
Jul    25    24    20    25
Aug    23    23    19    20
Sep    18    19    16    17
Okt    15    14    15    14
Nov     9     8     7     9
Dez     5     4     6     2 

      2021   2022   2023   2024
Jan   True   True  False  False
Feb  False  False  False   True
Mär  False  False  False  False
Apr  False  False  False  False
Mai  False  False  False  False
Jun  False  False  False  False
Jul  False  False  False  False
Aug  False  False  False  False
Sep  False  False  False  False
Okt  False  False  False  False
Nov  False  False  False  False
Dez  False  False  False   True

Für ein NumPy-Array wird die Übereinstimmung elementweise überprüft (vergleiche zum nächsten Reiter).

print(type(temperaturen[2021].values), "\n")

print(temperaturen.isin(temperaturen[2021].values))
<class 'numpy.ndarray'> 

     2021   2022   2023   2024
Jan  True  False  False  False
Feb  True  False  False   True
Mär  True   True   True   True
Apr  True  False   True  False
Mai  True   True   True  False
Jun  True  False  False  False
Jul  True  False  False   True
Aug  True   True   True  False
Sep  True   True  False  False
Okt  True  False   True  False
Nov  True  False   True   True
Dez  True   True  False   True

Für eine Series wird die Übereinstimmung positionsweise geprüft (vergleiche zum vorherigen Reiter). Der Index muss übereinstimmen.

print(temperaturen.isin(temperaturen[2021]), "\n")

temperaturen_2021_falscher_index = pd.Series([2, 4, 7, 12, 19, 23, 25, 23, 18, 15, 9, 5])
temperaturen_2021_falscher_index.index = ['A', 'B', 'C', 'D', 'E', 'F', 'Jul', 'Aug', 'Sep', 'Okt', 'Nov', 'Dez']

print("Der Index der Series lautet:\n['A', 'B', 'C', 'D', 'E', 'F', 'Jul', 'Aug', 'Sep', 'Okt', 'Nov', 'Dez'].\nDas Ergebnis an den Indexpositionen A-F ist immer False.")
print(temperaturen.isin(temperaturen_2021_falscher_index))
     2021   2022   2023   2024
Jan  True  False  False  False
Feb  True  False  False  False
Mär  True  False  False  False
Apr  True  False  False  False
Mai  True  False  False  False
Jun  True  False  False  False
Jul  True  False  False   True
Aug  True   True  False  False
Sep  True  False  False  False
Okt  True  False   True  False
Nov  True  False  False   True
Dez  True  False  False  False 

Der Index der Series lautet:
['A', 'B', 'C', 'D', 'E', 'F', 'Jul', 'Aug', 'Sep', 'Okt', 'Nov', 'Dez'].
Das Ergebnis an den Indexpositionen A-F ist immer False.
      2021   2022   2023   2024
Jan  False  False  False  False
Feb  False  False  False  False
Mär  False  False  False  False
Apr  False  False  False  False
Mai  False  False  False  False
Jun  False  False  False  False
Jul   True  False  False   True
Aug   True   True  False  False
Sep   True  False  False  False
Okt   True  False   True  False
Nov   True  False  False   True
Dez   True  False  False  False

Für einen DataFrame wird die Übereinstimmung positionsweise geprüft. Index und Spaltennamen müssen übereinstimmen (Index siehe Reiter Series).

temperaturen_2021_df = pd.DataFrame(temperaturen[2021])
print(temperaturen.isin(temperaturen_2021_df), "\n")

temperaturen_2021_df.columns = [2035]
print(temperaturen.isin(temperaturen_2021_df), "\n")
     2021   2022   2023   2024
Jan  True  False  False  False
Feb  True  False  False  False
Mär  True  False  False  False
Apr  True  False  False  False
Mai  True  False  False  False
Jun  True  False  False  False
Jul  True  False  False  False
Aug  True  False  False  False
Sep  True  False  False  False
Okt  True  False  False  False
Nov  True  False  False  False
Dez  True  False  False  False 

      2021   2022   2023   2024
Jan  False  False  False  False
Feb  False  False  False  False
Mär  False  False  False  False
Apr  False  False  False  False
Mai  False  False  False  False
Jun  False  False  False  False
Jul  False  False  False  False
Aug  False  False  False  False
Sep  False  False  False  False
Okt  False  False  False  False
Nov  False  False  False  False
Dez  False  False  False  False 
Tipp 2.1: Überraschungen vermeiden

Eine klassenabhängige Funktionsausführung kann, wenn das Verhalten unbemerkt bleibt, die Ergebnisse einer Datenanalyse verfälschen. Um dies zu verhindern, sollten Sie 3 allgemeine Ratschläge befolgen:

  1. Schauen Sie in die Dokumentation der jeweiligen Funktion. Python und viele Module entwickeln sich dynamisch, sodass sich das Verhalten einer Funktion verändern kann.

  2. Gehen Sie schrittweise vor und lassen sich die Zwischenergebnisse von Arbeitsschritten mit der Funktion print() ausgeben.

  3. Bei großen Datenmengen ist es häufig einfacher, mit eigens erzeugten Testdaten zu arbeiten. Ein zehnzeiliger DataFrame mit den Datentypen und der Struktur der Arbeitsdaten, ist leichter zu überblicken. Nutzen Sie einen solchen Testdatensatz um die von Ihnen verwendeten Funktionen zu überprüfen.

Eine Gruppe von Funktionen setzt logische Vergleiche um.

Funktion Vergleich
pd.DataFrame.lt(other) kleiner
pd.DataFrame.le(other) kleiner gleich
pd.DataFrame.eq(other) gleich
pd.DataFrame.ne(other) ungleich
pd.DataFrame.ge(other) größer gleich
pd.DataFrame.gt(other) größer
print(temperaturen.le(2), "\n")
print(temperaturen[2021].gt(5))
      2021   2022   2023   2024
Jan   True  False   True   True
Feb  False  False   True   True
Mär  False  False  False  False
Apr  False  False  False  False
Mai  False  False  False  False
Jun  False  False  False  False
Jul  False  False  False  False
Aug  False  False  False  False
Sep  False  False  False  False
Okt  False  False  False  False
Nov  False  False  False  False
Dez  False  False  False   True 

Jan    False
Feb    False
Mär     True
Apr     True
Mai     True
Jun     True
Jul     True
Aug     True
Sep     True
Okt     True
Nov     True
Dez    False
Name: 2021, dtype: bool

Verwendung der Methoden .agg() und .apply()

Pandas bringt zwei eigene Methoden mit, um Operationen zeilen- oder spaltenweise auszuführen. DataFrame.agg() (oder auch DataFrame.aggregate()) aggregiert einen DataFrame zeilen- oder spaltenweise durch eine Funktion. Die Pandas-Methode DF.apply() wendet eine Funktion zeilen- oder spaltenweise auf einen DataFrame an. Die Methoden sind also sehr ähnlich und führen in den meisten Fällen zum selben Ergebnis.

Beide Funktionen führen mit dem Argument axis = 1 Operationen zeilenweise aus.

def my_plus_ten(x):
  y = x + 10
  return y

print(temperaturen.agg(my_plus_ten), "\n")
print(temperaturen.apply(my_plus_ten))
     2021  2022  2023  2024
Jan    12    13     7     9
Feb    14    16     9    12
Mär    17    19    14    15
Apr    22    23    19    18
Mai    29    28    25    27
Jun    33    31    30    34
Jul    35    34    30    35
Aug    33    33    29    30
Sep    28    29    26    27
Okt    25    24    25    24
Nov    19    18    17    19
Dez    15    14    16    12 

     2021  2022  2023  2024
Jan    12    13     7     9
Feb    14    16     9    12
Mär    17    19    14    15
Apr    22    23    19    18
Mai    29    28    25    27
Jun    33    31    30    34
Jul    35    34    30    35
Aug    33    33    29    30
Sep    28    29    26    27
Okt    25    24    25    24
Nov    19    18    17    19
Dez    15    14    16    12
print(temperaturen.agg("sum"), "\n")
print(temperaturen.apply("sum"))
2021    162
2022    162
2023    127
2024    142
dtype: int64 

2021    162
2022    162
2023    127
2024    142
dtype: int64
print(temperaturen.agg(["sum", "mean", "median"]), "\n")
print(temperaturen.apply(["sum", "mean", "median"]))
         2021   2022        2023        2024
sum     162.0  162.0  127.000000  142.000000
mean     13.5   13.5   10.583333   11.833333
median   13.5   13.5   12.000000   11.500000 

         2021   2022        2023        2024
sum     162.0  162.0  127.000000  142.000000
mean     13.5   13.5   10.583333   11.833333
median   13.5   13.5   12.000000   11.500000
print(temperaturen.agg({2021: "sum", 2022: "mean", 2023: "median", 2024: "min"}), "\n")
print(temperaturen.apply({2021: "sum", 2022: "mean", 2023: "median", 2024: "min"}), "\n")
2021    162.0
2022     13.5
2023     12.0
2024     -1.0
dtype: float64 

2021    162.0
2022     13.5
2023     12.0
2024     -1.0
dtype: float64 

Besonders nützlich ist die Möglichkeit, Funktionen, die normalerweise auf eine Series angewendet werden, auf jedes Element der Series anzuwenden. Dafür wird die lambda Syntax verwendet: lambda x: x + 1. lambda ist ein Platzhalter und kann als “für jedes x tue:” gelesen werden. So kann beispielsweise die Anzahl der Zeichen in jeder Zeile bestimmt werden.

# Auf die Series angewendet
print(len(str(temperaturen[2021])), "\n")

# Elementweise angewendet
print(temperaturen[2021].agg(lambda x: len(str(x))), "\n") # deprecated
print(temperaturen[2021].apply(lambda x: len(str(x))), "\n")
144 

Jan    1
Feb    1
Mär    1
Apr    2
Mai    2
Jun    2
Jul    2
Aug    2
Sep    2
Okt    2
Nov    1
Dez    1
Name: 2021, dtype: int64 

Jan    1
Feb    1
Mär    1
Apr    2
Mai    2
Jun    2
Jul    2
Aug    2
Sep    2
Okt    2
Nov    1
Dez    1
Name: 2021, dtype: int64 

Details zur Verwendung des Lambda-Ausdrucks finden Sie in der Dokumentation.

Der Vollständigkeit wegen ist zu erwähnen, dass mit den Methoden .map() und .transform() weitere, sehr ähnliche Alternativen bestehen. Bei Interesse können Sie die Unterschiede in diesem Artikel nachlesen.

# print(temperaturen[2021].map(lambda x: len(str(x))))
# print(temperaturen[2021].transform(lambda x: len(str(x))), "\n") 

2.2 Aufgaben Operationen

Gegeben ist der DataFrame temperaturen.

# Temperaturdaten
temperaturen_2021 = pd.Series([2, 4, 7, 12, 19, 23, 25, 23, 18, 15, 9, 5])
temperaturen_2022 = pd.Series([3, 6, 9, 13, 18, 21, 24, 23, 19, 14, 8, 4])
temperaturen_2023 = pd.Series([-3, -1, 4, 9, 15, 20, 20, 19, 16, 15, 7, 6])
temperaturen_2024 = pd.Series([-1, 2, 5, 8, 17, 24, 25, 20, 17, 14, 9, 2])

# DataFrame erzeugen
temperaturen = pd.concat([temperaturen_2021, temperaturen_2022, temperaturen_2023, temperaturen_2024], axis = 1)
temperaturen.columns = [2021, 2022, 2023, 2024]
temperaturen.index = ['Jan', 'Feb', 'Mär', 'Apr', 'Mai', 'Jun', 'Jul', 'Aug', 'Sep', 'Okt', 'Nov', 'Dez']
  1. Bestimmen Sie für den Dataframe temperaturen die monatliche Mediantemperatur.

  2. Ermitteln Sie die Monate mit einer Mediantemperatur größer gleich 21 Grad.

  3. Geben Sie die Indexbeschriftung dieser Monate aus.

  1. Aufgabe
print(temperaturen.mean(axis = 1))
Jan     0.25
Feb     2.75
Mär     6.25
Apr    10.50
Mai    17.25
Jun    22.00
Jul    23.50
Aug    21.25
Sep    17.50
Okt    14.50
Nov     8.25
Dez     4.25
dtype: float64
  1. Aufgabe
print(temperaturen.mean(axis = 1).ge(21))
Jan    False
Feb    False
Mär    False
Apr    False
Mai    False
Jun     True
Jul     True
Aug     True
Sep    False
Okt    False
Nov    False
Dez    False
dtype: bool
  1. Aufgabe
print(temperaturen.index[temperaturen.mean(axis = 1).ge(21)], "\n")

# als Liste
print(list(temperaturen.index[temperaturen.mean(axis = 1).ge(21)]), "\n")
Index(['Jun', 'Jul', 'Aug'], dtype='object') 

['Jun', 'Jul', 'Aug'] 

2.3 Suchen und ersetzen

Um die Indexposition eines bestimmten Werts zu bestimmen, kann die Numpy-Funktion np.where() verwendet werden. Diese gibt zwei Arrays mit den jeweiligen Zeilen- und Spaltennummern zurück.

print(np.where(temperaturen == 4))
(array([ 1,  2, 11]), array([0, 2, 1]))

Unter anderem befindet sich der Wert 4 in Zeile 1 in Spalte 0 oder auch in Zeile 2 in Spalte 2.

print(temperaturen.iloc[1, 0])
print(temperaturen.iloc[2, 2])
4
4

Pandas bietet zwei Methoden, um Werte zu ersetzen.

  • pd.DataFrame.replace(to_replace, value, *, inplace = False) ersetzt to_replace mit value. Mit dem Argument inplace = True erfolgt dies direkt im Objekt.

  • pd.where(cond, other = nan, inplace = False) behält cond und ersetzt alle anderen Werte mit other (standardmäßig ein Platzhalter für fehlende Werte). Mit dem Argument inplace = True erfolgt dies direkt im Objekt.

Die Syntax beider Funktionen unterscheidet sich leicht, wie im folgenden Beispiel zu sehen ist.

print(temperaturen.replace(to_replace = 25, value = 1000), "\n")
print(temperaturen.where(temperaturen == 25, other = 1000))
     2021  2022  2023  2024
Jan     2     3    -3    -1
Feb     4     6    -1     2
Mär     7     9     4     5
Apr    12    13     9     8
Mai    19    18    15    17
Jun    23    21    20    24
Jul  1000    24    20  1000
Aug    23    23    19    20
Sep    18    19    16    17
Okt    15    14    15    14
Nov     9     8     7     9
Dez     5     4     6     2 

     2021  2022  2023  2024
Jan  1000  1000  1000  1000
Feb  1000  1000  1000  1000
Mär  1000  1000  1000  1000
Apr  1000  1000  1000  1000
Mai  1000  1000  1000  1000
Jun  1000  1000  1000  1000
Jul    25  1000  1000    25
Aug  1000  1000  1000  1000
Sep  1000  1000  1000  1000
Okt  1000  1000  1000  1000
Nov  1000  1000  1000  1000
Dez  1000  1000  1000  1000

2.4 Aufgaben suchen und ersetzen

  1. Bestimmen Sie die Position der Werte im DataFrame ‘temperaturen’, die kleiner als 0 sind und geben Sie die Werte aus.

  2. Ersetzen Sie alle Werte im DataFrame ‘temperaturen’, die kleiner sind als 0 durch den Wert 0 und geben Sie das Ergebnis aus.

  1. Aufgabe
print(np.where(temperaturen <= 0))
print("Anzahl Werte:", len(np.where(temperaturen <= 0)[0]))

for i in range(len(np.where(temperaturen <= 0)[0])):
  print(temperaturen.iloc[np.where(temperaturen <= 0)[0][i], np.where(temperaturen <= 0)[1][i]])
(array([0, 0, 1]), array([2, 3, 2]))
Anzahl Werte: 3
-3
-1
-1
  1. Aufgabe
print(temperaturen.where(temperaturen > 0, other = 0))
     2021  2022  2023  2024
Jan     2     3     0     0
Feb     4     6     0     2
Mär     7     9     4     5
Apr    12    13     9     8
Mai    19    18    15    17
Jun    23    21    20    24
Jul    25    24    20    25
Aug    23    23    19    20
Sep    18    19    16    17
Okt    15    14    15    14
Nov     9     8     7     9
Dez     5     4     6     2

2.5 Sortieren

Die Methode DataFrame.sort_index(axis = 0, ascending = True, inplace = False) sortiert entlang einer Achse, standardmäßig aufsteigend nach dem Index. Durch die Übergabe des Arguments axis = 1 werden die Spalten sortiert. Mit dem Argument ascending = False wird absteigend sortiert. Das Argument inplace = True sorgt, wie gewohnt, dafür, dass das Ergebnis des Sortiervorgangs direkt im Objekt gespeichert wird.

print(temperaturen.sort_index(), "\n")
print(temperaturen.sort_index(axis = 1, ascending = False))
     2021  2022  2023  2024
Apr    12    13     9     8
Aug    23    23    19    20
Dez     5     4     6     2
Feb     4     6    -1     2
Jan     2     3    -3    -1
Jul    25    24    20    25
Jun    23    21    20    24
Mai    19    18    15    17
Mär     7     9     4     5
Nov     9     8     7     9
Okt    15    14    15    14
Sep    18    19    16    17 

     2024  2023  2022  2021
Jan    -1    -3     3     2
Feb     2    -1     6     4
Mär     5     4     9     7
Apr     8     9    13    12
Mai    17    15    18    19
Jun    24    20    21    23
Jul    25    20    24    25
Aug    20    19    23    23
Sep    17    16    19    18
Okt    14    15    14    15
Nov     9     7     8     9
Dez     2     6     4     5

Die Methode DataFrame.sort_values(by, *, axis = 0, ascending = True, inplace = False) sortiert Werte entlang einer Achse, standardmäßig entlang des Index (axis = 0). Dem Parameter by sind laut Dokumentation der Spaltenname als string bzw. eine Liste von Spaltennamen als string zu übergeben, nach denen sortiert werden soll. Wie im folgenden Code-Beispiel zu sehen ist, muss die numerische Spaltenbeschriftung jedoch auch in numerischer Form übergeben werden.

Wird mit dem Argument axis = 1 entlang der zweiten Dimension sortiert, werden entsprechend Indexbeschriftungen übergeben.

# Sortieren nach numerischen Spaltenbeschriftungen
print(temperaturen.sort_values(by = 2021), "\n")
print(temperaturen.sort_values(by = [2021, 2023]), "\n")

# Sortieren nach als string übergebenen Spaltenbeschriftungen
# führt zu KeyError, die Fehlermeldung wird nicht vollständig abgefangen
try:
  print(temperaturen.sort_values(by = '2021'))
except Exception as error:
  print(error)
     2021  2022  2023  2024
Jan     2     3    -3    -1
Feb     4     6    -1     2
Dez     5     4     6     2
Mär     7     9     4     5
Nov     9     8     7     9
Apr    12    13     9     8
Okt    15    14    15    14
Sep    18    19    16    17
Mai    19    18    15    17
Jun    23    21    20    24
Aug    23    23    19    20
Jul    25    24    20    25 

     2021  2022  2023  2024
Jan     2     3    -3    -1
Feb     4     6    -1     2
Dez     5     4     6     2
Mär     7     9     4     5
Nov     9     8     7     9
Apr    12    13     9     8
Okt    15    14    15    14
Sep    18    19    16    17
Mai    19    18    15    17
Aug    23    23    19    20
Jun    23    21    20    24
Jul    25    24    20    25 

'2021'

2.6 Aufgaben Sortieren

  1. Sortieren Sie den DataFrame ‘meerschweinchen’ absteigend nach der Zahnlänge (‘len’). Welches Meerschweinchen hat die längste zahnbildende Zelle (gesucht ist die ID)?

  2. Welches Meerschweinchen, welches die Dosis 1.0 erhielt, hat die längste zahnbildende Zelle (gesucht ist die ID)?

  1. Aufgabe
print(meerschweinchen.sort_values(by = 'len', ascending = False).head(), "\n")

print("Die ID lautet:", meerschweinchen.sort_values(by = 'len', ascending = False).iloc[0, 0])
    ID   len supp  dose
22  23  33.9   VC   2.0
25  26  32.5   VC   2.0
55  56  30.9   OJ   2.0
29  30  29.5   VC   2.0
58  59  29.4   OJ   2.0 

Die ID lautet: 23
  1. Aufgabe
dose_1 = meerschweinchen[meerschweinchen['dose'] == 1.0]

print(dose_1.sort_values(by = 'len', ascending = False).head(), "\n")

print("Die ID lautet:", dose_1.sort_values(by = 'len', ascending = False).iloc[0, 0])
    ID   len supp  dose
49  50  27.3   OJ   1.0
43  44  26.4   OJ   1.0
46  47  25.8   OJ   1.0
45  46  25.2   OJ   1.0
42  43  23.6   OJ   1.0 

Die ID lautet: 50

2.7 GroupBy

Die Methode pd.groupby() teilt einen DataFrame (oder eine Series) in Gruppen auf und gibt ein GroupBy-Objekt zurück. Das GroupBy-Objekt hat dieselben Spalten- und Zeilenbeschriftungen wie der DataFrame, das GroupBy-Objekt ist aber nach der Gruppenaufteilung sortiert. Operationen, die auf das GroupBy-Objekt angewendet werden, werden für jede Gruppe separat ausgeführt.

Dies kann am Datensatz ‘meerschweinchen’ im folgenden Panel nachvollzogen werden.

  1. Reiter: Der Datensatz enthält 60 Einträge. Die ersten 30 Einträge haben in der Spalte ‘supp’ die Ausprägung VC für Vitamin C, die letzten 30 Einträge die Ausprägung OJ für Orangensaft.

  2. Reiter: Mit der Methode pd.groupby('supp') kann der Datensatz nach den Merkmalsausprägungen in der Spalte ‘dose’ (0.5, 1 und 2) gruppiert werden.

  3. Reiter: Auf das Groupby-Objekt können Operationen ausgeführt werden. Beispielsweise kann die Spalte ‘len’ ausgewählt und mit der Methode .mean() die mittlere Länge der zahnbildenden Zelle bestimmt werden.

  4. Reiter: Ebenso kann nach den Ausprägungen mehrerer Merkmale gruppiert werden, indem diese als Liste übergeben werden pd.groupby(by = ['supp', 'dose']).

print(meerschweinchen.head(n = 12))
    ID   len supp  dose
0    1   4.2   VC   0.5
1    2  11.5   VC   0.5
2    3   7.3   VC   0.5
3    4   5.8   VC   0.5
4    5   6.4   VC   0.5
5    6  10.0   VC   0.5
6    7  11.2   VC   0.5
7    8  11.2   VC   0.5
8    9   5.2   VC   0.5
9   10   7.0   VC   0.5
10  11  16.5   VC   1.0
11  12  16.5   VC   1.0

Für die Methode .head() wurde das Argument n halbiert, um die gleiche Zeilenzahl in der Ausgabe anzeigen zu lassen, da auch diese Methode für jede der beiden Gruppen (VC und OJ) ausgeführt wird.

print(meerschweinchen.groupby('supp').head(n = 6))
    ID   len supp  dose
0    1   4.2   VC   0.5
1    2  11.5   VC   0.5
2    3   7.3   VC   0.5
3    4   5.8   VC   0.5
4    5   6.4   VC   0.5
5    6  10.0   VC   0.5
30  31  15.2   OJ   0.5
31  32  21.5   OJ   0.5
32  33  17.6   OJ   0.5
33  34   9.7   OJ   0.5
34  35  14.5   OJ   0.5
35  36  10.0   OJ   0.5
print(meerschweinchen.groupby(by = 'supp')['len'].mean())
supp
OJ    20.663333
VC    16.963333
Name: len, dtype: float64
print(meerschweinchen.groupby(by = ['supp', 'dose'])['len'].mean())
supp  dose
OJ    0.5     13.23
      1.0     22.70
      2.0     26.06
VC    0.5      7.98
      1.0     16.77
      2.0     26.14
Name: len, dtype: float64

2.8 Aufgaben GroupBy

Der Datensatz Motor Trend Car Road Tests (mtcars) stammt aus der us-amerikanischen Zeitschrift Motor Trend von 1974 und enthalt Daten für 32 Autos.

mtcars = pd.read_csv(filepath_or_buffer = "01-daten/mtcars.csv", sep = ",")
mtcars.rename(columns = {'Unnamed: 0': 'car'}, inplace = True)

mtcars.head()
car mpg cyl disp hp drat wt qsec vs am gear carb
0 Mazda RX4 21.0 6 160.0 110 3.90 2.620 16.46 0 1 4 4
1 Mazda RX4 Wag 21.0 6 160.0 110 3.90 2.875 17.02 0 1 4 4
2 Datsun 710 22.8 4 108.0 93 3.85 2.320 18.61 1 1 4 1
3 Hornet 4 Drive 21.4 6 258.0 110 3.08 3.215 19.44 1 0 3 1
4 Hornet Sportabout 18.7 8 360.0 175 3.15 3.440 17.02 0 0 3 2
Code-Block 2.1
Spalte Bedeutung
mpg Kraftstoffverbrauch in Meilen pro Gallone
cyl Anzahl Zylinder
disp Hubraum in Kubikzoll
hp Pferdestärken
drat Hinterachsübersetzung
wt Gewicht in 1000 Pfund
qsec Zeit auf der Viertelmeile
vs Motor (0 = V-Motor, 1 = Reihenmotor)
am Schaltung (0 = Automatik, 1 = Handschaltung)
gear Anzahl der Vorwärtsgänge
carb Anzahl der Vergaser

Henderson and Velleman 1981. Building multiple regression models interactively. Biometrics 37: 391–411. Der Datensatz ist abrufbar auf GitHub und in R verfügbar.

 

  1. Gruppieren Sie den Datensatz nach der Anzahl Zylinder und ermitteln Sie den durchschnittlichen Kraftstoffverbrauch für jede Gruppe.

  2. Wie viele Liter auf 100 Kilometer sind es?

  3. Gruppieren Sie den Datensatz nach der Anzahl der Zylinder und der Vergaser. Welche Gruppe ist am schnellsten auf der Viertelmeile?

  1. Aufgabe
mtcars.groupby(by = 'cyl')['mpg'].mean() 
cyl
4    26.663636
6    19.742857
8    15.100000
Name: mpg, dtype: float64
  1. Aufgabe
# 1 Meile = 1.60934 Kilometer
# 1 Gallone = 3.78541 Liter

mpg = mtcars.groupby(by = 'cyl')['mpg'].mean()

liter_100km = 1 / mpg.mul(1.60934).div(3.78541).div(100)

print(liter_100km)
cyl
4     8.821567
6    11.913932
8    15.577156
Name: mpg, dtype: float64
  1. Aufgabe
print(mtcars.groupby(by = ['cyl', 'carb'])['qsec'].mean(), "\n")
print(mtcars.groupby(by = ['cyl', 'carb'])['qsec'].mean().index[-1], "\n")
cyl  carb
4    1       19.378000
     2       18.936667
6    1       19.830000
     4       17.670000
     6       15.500000
8    2       17.060000
     3       17.666667
     4       16.495000
     8       14.600000
Name: qsec, dtype: float64 

(np.int64(8), np.int64(8)) 

Die Gruppe mit 8 Zylindern und 8 Vergasern ist am schnellsten. (Hinweis: Es handelt sich hierbei um einen sogenannten MultiIndex.)