Deskriptive Statistik

pandas-Objekte sind mit einer Reihe von gängigen mathematischen und statistischen Methoden ausgestattet. Die meisten von ihnen fallen in die Kategorie der Reduktionen oder zusammenfassenden Statistiken, Methoden, die einen einzelnen Wert (wie die Summe oder den Mittelwert) aus einer Serie oder einer Reihe von Werten aus den Zeilen oder Spalten eines DataFrame extrahieren. Im Vergleich zu ähnlichen Methoden, die sich bei NumPy-Arrays finden, behandeln sie auch fehlende Daten.

[1]:
import numpy as np
import pandas as pd


rng = np.random.default_rng()
df = pd.DataFrame(
    rng.normal(size=(7, 3)),
    index=pd.date_range("2022-02-02", periods=7),
)
new_index = pd.date_range("2022-02-03", periods=7)
df2 = df.reindex(new_index)

df2
[1]:
0 1 2
2022-02-03 0.139876 -0.730735 -0.467788
2022-02-04 0.561951 1.125547 -0.801495
2022-02-05 0.255746 -0.735519 -0.659993
2022-02-06 0.227345 -1.646032 -0.282293
2022-02-07 1.393767 0.118605 -0.535032
2022-02-08 0.828147 0.473280 0.175779
2022-02-09 NaN NaN NaN

Der Aufruf der pandas.DataFrame.sum-Methode gibt eine Serie zurück, die Spaltensummen enthält:

[2]:
df2.sum()
[2]:
0    3.406833
1   -1.394854
2   -2.570822
dtype: float64

Die Übergabe von axis='columns' oder axis=1 summiert stattdessen über die Spalten:

[3]:
df2.sum(axis="columns")
[3]:
2022-02-03   -1.058647
2022-02-04    0.886003
2022-02-05   -1.139765
2022-02-06   -1.700981
2022-02-07    0.977340
2022-02-08    1.477206
2022-02-09    0.000000
Freq: D, dtype: float64

Wenn eine ganze Zeile oder Spalte alle NA-Werte enthält, ist die Summe 0. Dies kann mit der Option skipna deaktiviert werden:

[4]:
df2.sum(axis="columns", skipna=False)
[4]:
2022-02-03   -1.058647
2022-02-04    0.886003
2022-02-05   -1.139765
2022-02-06   -1.700981
2022-02-07    0.977340
2022-02-08    1.477206
2022-02-09         NaN
Freq: D, dtype: float64

Einige Aggregationen, wie z.B. mean, erfordern mindestens einen Nicht-NaN-Wert, um ein wertvolles Ergebnis zu erhalten:

[5]:
df2.mean(axis="columns")
[5]:
2022-02-03   -0.352882
2022-02-04    0.295334
2022-02-05   -0.379922
2022-02-06   -0.566994
2022-02-07    0.325780
2022-02-08    0.492402
2022-02-09         NaN
Freq: D, dtype: float64

Optionen für Reduktionsmethoden

Methode

Beschreibung

axis

die Achse der zu reduzierenden Werte: 0 für die Zeilen des DataFrame und 1 für die Spalten

skipna

fehlende Werte ausschließen; standardmäßig True

level

nach Ebene gruppiert reduzieren, wenn die Achse hierarchisch indiziert ist (MultiIndex)

Einige Methoden, wie idxmin und idxmax, liefern indirekte Statistiken wie den Indexwert, bei dem der Mindest- oder Höchstwert erreicht wird:

[6]:
df2.idxmax()
[6]:
0   2022-02-07
1   2022-02-04
2   2022-02-08
dtype: datetime64[ns]

Andere Methoden sind Akkumulationen:

[7]:
df2.cumsum()
[7]:
0 1 2
2022-02-03 0.139876 -0.730735 -0.467788
2022-02-04 0.701828 0.394812 -1.269283
2022-02-05 0.957574 -0.340707 -1.929276
2022-02-06 1.184919 -1.986739 -2.211569
2022-02-07 2.578686 -1.868134 -2.746601
2022-02-08 3.406833 -1.394854 -2.570822
2022-02-09 NaN NaN NaN

Eine andere Art von Methoden sind weder Reduktionen noch Akkumulationen. describe ist ein solches Beispiel, das mehrere zusammenfassende Statistiken auf einen Schlag erstellt:

[8]:
df2.describe()
[8]:
0 1 2
count 6.000000 6.000000 6.000000
mean 0.567805 -0.232476 -0.428470
std 0.478841 0.996497 0.344133
min 0.139876 -1.646032 -0.801495
25% 0.234445 -0.734323 -0.628752
50% 0.408849 -0.306065 -0.501410
75% 0.761598 0.384611 -0.328667
max 1.393767 1.125547 0.175779

Bei nicht-numerischen Daten erzeugt describe alternative zusammenfassende Statistiken:

[9]:
data = {
    "Code": ["U+0000", "U+0001", "U+0002", "U+0003", "U+0004", "U+0005"],
    "Octal": ["001", "002", "003", "004", "004", "005"],
}
df3 = pd.DataFrame(data)

df3.describe()
[9]:
Code Octal
count 6 6
unique 6 5
top U+0000 004
freq 1 2

Deskriptive und zusammenfassende Statistiken:

Methode

Beschreibung

count

Anzahl der Nicht-NA-Werte

describe

Berechnung einer Reihe von zusammenfassenden Statistiken für Serien oder jede DataFrame-Spalte

min, max

Berechnung der Mindest- und Höchstwerte

argmin, argmax

Berechnung der Indexstellen (ganze Zahlen), an denen der Mindest- bzw. Höchstwert erreicht wurde

idxmin, idxmax

Berechnung der Indexbeschriftungen, an denen der Mindest- bzw. Höchstwert erreicht wurde

quantile

Berechnung des Stichprobenquantils im Bereich von 0 bis 1

sum

Summe der Werte

mean

Arithmetisches Mittel der Werte

median

Arithmetischer Median (50%-Quantil) der Werte

mad

Mittlere absolute Abweichung vom Mittelwert

prod

Produkt aller Werte

var

Stichprobenvarianz der Werte

std

Stichprobenstandardabweichung der Werte

skew

Stichprobenschiefe (drittes Moment) der Werte

kurt

Stichprobenwölbung (viertes Moment) der Werte

cumsum

Kumulierte Summe der Werte

cummin, cummax

Kumuliertes Minimum bzw. Maximum der Werte

cumprod

Kumuliertes Produkt der Werte

diff

Berechnung der ersten arithmetischen Differenz (nützlich für Zeitreihen)

pct_change

Berechnung der prozentualen Veränderungen

ydata_profiling

ydata-profiling erzeugt Profilberichte aus einem pandas DataFrame. Die Funktion pandas df.describe() ist praktisch, aber ein wenig einfach für die explorative Datenanalyse. ydata-profiling erweitert pandas DataFrame mit df.profile_report(), die automatisch einen standardisierten Bericht zum Verständnis der Daten erzeugt.

Installation

$ uv add standard-imghdr legacy-cgi "ydata-profiling[notebook, unicode]"
Resolved 251 packages in 2.53s
Prepared 1 package in 106ms
Installed 24 packages in 155ms
 + annotated-types==0.7.0
 + dacite==1.9.2
 + htmlmin==0.1.12
 + imagehash==4.3.1
 + legacy-cgi==2.6.3
 + llvmlite==0.44.0
 + multimethod==1.12
 + networkx==3.5
 + numba==0.61.0
 + patsy==1.0.1
 + phik==0.12.4
 + puremagic==1.29
 + pydantic==2.11.7
 + pydantic-core==2.33.2
 + pywavelets==1.8.0
 + seaborn==0.13.2
 + standard-imghdr==3.13.0
 + statsmodels==0.14.4
 + tangled-up-in-unicode==0.2.0
 + typeguard==4.4.2
 + typing-inspection==0.4.1
 + visions==0.8.1
 + wordcloud==1.9.4
 + ydata-profiling==4.16.1
$ uv run jupyter notebook

In Python 3.13 wurden die Module imghdr und cgi entfernt, siehe auch PEP 594. Als Abhilfe für diese Legacy-Produkte wurden jedoch standard-imghdr und legacy-cgi im Python Package Index bereitgestellt.

Beispiel

[10]:
from ydata_profiling import ProfileReport


profile = ProfileReport(df2, title="Pandas Profiling Report")

profile.to_notebook_iframe()
Upgrade to ydata-sdk

Improve your data and profiling with ydata-sdk, featuring data quality scoring, redundancy detection, outlier identification, text validation, and synthetic data generation.


100%|██████████████████████████████████████████| 3/3 [00:00<00:00, 39077.37it/s]

Konfiguration für große Datensätze

Standardmäßig fasst ydata-profiling den Datensatz so zusammen, dass er die meisten Erkenntnisse für die Datenanalyse liefert. Wenn die Berechnungszeit der Profilerstellung zu einem Engpass wird, bietet ydata-profiling mehrere Alternativen, um diesen zu überwinden. Für die folgenden Beispiele lesen wir zunächst einen größeren Datensatz in pandas ein:

[11]:
titanic = pd.read_csv(
    "https://raw.githubusercontent.com/datasciencedojo/datasets/master/titanic.csv"
)

1. Minimaler Modus

ydata-profiling enthält eine minimale Konfigurationsdatei config_minimal.yaml, in der die teuersten Berechnungen standardmäßig ausgeschaltet sind. Dies ist die empfohlene Ausgangsbasis für größere Datensätze.

[12]:
profile = ProfileReport(
    titanic, title="Minimal Pandas Profiling Report", minimal=True
)

profile.to_notebook_iframe()

  0%|                                                    | 0/12 [00:00<?, ?it/s]
100%|██████████████████████████████████████████| 12/12 [00:00<00:00, 105.09it/s]

Weitere Details zu Einstellungen und Konfiguration findet ihr unter Available settings.

2. Stichprobe

Eine alternative Möglichkeit bei sehr großen Datensätzen besteht darin, nur einen Teil davon für die Erstellung des Profiling-Berichts zu verwenden:

[13]:
sample = titanic.sample(frac=0.05)
profile = ProfileReport(sample, title="Sample Pandas Profiling Report")

profile.to_notebook_iframe()

100%|███████████████████████████████████████| 12/12 [00:00<00:00, 230879.12it/s]

3. Teure Berechnungen deaktivieren

Um den Rechenaufwand in großen Datensätzen zu verringern, aber dennoch einige interessante Informationen zu erhalten, können einige Berechnungen nur für bestimmte Spalten gefiltert werden:

[14]:
profile = ProfileReport()
profile.config.interactions.targets = ["Sex", "Age"]
profile.df = titanic

profile.to_notebook_iframe()

100%|███████████████████████████████████████| 12/12 [00:00<00:00, 234100.69it/s]

Die Einstellung interactions.targets, kann sowohl über Konfigurationsdateien wie auch über Umgebungsvariablen geändert werden; Einzelheiten hierzu findet ihr unter Changing settings.

4. Nebenläufigkeit

Aktuell wird an einem skalierbaren Spark-Backend für ydata-profiling gearbeitet, siehe Spark Profiling Development.