Deskriptive Statistik und Normalitätstests
Berechnen Sie Schiefe und Kurtosis mit scipy.stats, führen Sie einen Shapiro-Wilk-Test auf Normalverteilung durch und interpretieren Sie den p-Wert.
Deskriptive Statistik und Normalitätstests ist eine kostenlose Pandas & NumPy Academy-Lektion auf CoddyKit. Dies ist Lektion 1 von 4. Du kannst die komplette Lektion unten kostenlos lesen – dann übst du sie direkt im Browser mit einem integrierten Code-Editor und einem KI-Tutor rund um die Uhr. Sie ist Teil des Pandas & NumPy Academy-Lernpfads, und dein Fortschritt wird über Web und CoddyKit-App synchronisiert. Der Pandas & NumPy Academy-Kurs umfasst insgesamt 4 Lektionen.
Teile dieser Lektion wurden noch nicht übersetzt und werden auf Englisch angezeigt.
Descriptive vs Inferential Statistics
Descriptive statistics summarise what is in your data: mean, median, standard deviation, skewness. Inferential statistics make claims about a population based on a sample: hypothesis tests, confidence intervals, p-values. SciPy's scipy.stats module bridges these worlds — it provides both descriptive measures that go beyond Pandas' describe() and the full suite of classical hypothesis tests. Combining Pandas for data manipulation and SciPy for statistical testing is the standard Python data science workflow.
Extended Descriptive Statistics
Pandas describe() gives count, mean, std, min/max, and quartiles. scipy.stats adds skewness (asymmetry of the distribution) and kurtosis (tail heaviness). Skewness of 0 means symmetric; positive skewness means a longer right tail (many small values, few very large). Kurtosis of 3 (or 0 in excess form) is normal; higher values indicate heavier tails with more extreme outliers than a normal distribution would produce.
import pandas as pd
from scipy import stats
import numpy as np
np.random.seed(0)
data = np.concatenate([
np.random.exponential(scale=2, size=500), # right-skewed
np.random.normal(loc=5, scale=1, size=500)
])
print('Mean:', round(data.mean(), 3))
print('Std:', round(data.std(), 3))
print('Skewness:', round(stats.skew(data), 3))
print('Kurtosis (excess):', round(stats.kurtosis(data), 3))Understanding Skewness
Skewness matters for choosing statistical tests and transformations. A right-skewed (positive skew) distribution has its mean larger than its median, typical of income data, reaction times, and sales amounts. A left-skewed (negative skew) distribution has its mean smaller than its median. Rule of thumb: |skewness| < 0.5 is approximately symmetric; 0.5–1.0 is moderately skewed; > 1.0 is highly skewed and may benefit from a log or square-root transformation before applying tests that assume normality.
import numpy as np
from scipy import stats
# Right-skewed: income-like data
right_skewed = np.random.lognormal(mean=1, sigma=1, size=1000)
print('Right skew:', round(stats.skew(right_skewed), 3))
# After log transform
print('After log transform:', round(stats.skew(np.log(right_skewed)), 3))
# Symmetric normal
normal_data = np.random.normal(0, 1, 1000)
print('Normal skew:', round(stats.skew(normal_data), 3))Why Normality Testing Matters
Many statistical tests — t-tests, ANOVA, Pearson correlation — assume that the data (or the residuals) follow a normal (Gaussian) distribution. If this assumption is violated with small samples, the test's p-values may be inaccurate. Normality testing checks whether the assumption holds. For large samples (n > 100), normality tests become very sensitive and will almost always reject normality for trivial deviations — in that case, rely on the Central Limit Theorem (sample means are approximately normal) rather than testing the raw data.
The Shapiro-Wilk Test
The Shapiro-Wilk test (scipy.stats.shapiro(data)) is the most powerful normality test for sample sizes up to about 5,000. It returns a W-statistic and a p-value. If p > 0.05, you fail to reject normality — the data is consistent with a normal distribution. If p ≤ 0.05, you reject normality. Remember: failing to reject normality does not prove the data is normal; it just means you do not have enough evidence to say it is not.
import numpy as np
from scipy import stats
np.random.seed(42)
# Normal data
normal = np.random.normal(0, 1, 100)
stat, p = stats.shapiro(normal)
print(f'Normal data: W={stat:.4f}, p={p:.4f}')
print('Conclusion:', 'Looks normal' if p > 0.05 else 'Not normal')
# Skewed data
skewed = np.random.exponential(1, 100)
stat2, p2 = stats.shapiro(skewed)
print(f'Skewed data: W={stat2:.4f}, p={p2:.4f}')
print('Conclusion:', 'Looks normal' if p2 > 0.05 else 'Not normal')The Kolmogorov-Smirnov Test
The Kolmogorov-Smirnov (K-S) test (scipy.stats.kstest(data, 'norm', args)) tests whether a sample follows a specified distribution. Unlike Shapiro-Wilk, it works for any distribution (not just normal) and for large samples. It computes the maximum difference between the empirical CDF of your data and the theoretical CDF. A variation, the two-sample K-S test (stats.ks_2samp(a, b)), tests whether two samples come from the same distribution — useful for comparing before/after distributions.
import numpy as np
from scipy import stats
np.random.seed(0)
data = np.random.normal(loc=5, scale=2, size=200)
# One-sample K-S test against N(5, 2) distribution
stat, p = stats.kstest(data, 'norm', args=(5, 2))
print(f'K-S test: stat={stat:.4f}, p={p:.4f}')
print('Follows N(5,2)?', 'Yes' if p > 0.05 else 'No')
# Two-sample K-S test
data2 = np.random.normal(loc=5.5, scale=2, size=200)
stat2, p2 = stats.ks_2samp(data, data2)
print(f'Two-sample K-S: stat={stat2:.4f}, p={p2:.4f}')Visual Normality Check: QQ Plot
The Q-Q (quantile-quantile) plot is a visual normality check: it plots the quantiles of your data against the quantiles of a normal distribution. If the data is normal, the points fall on a straight diagonal line. Deviations from the line indicate departure from normality — S-curves indicate kurtosis, bends indicate skewness. Statistical tests tell you if deviations are significant; Q-Q plots show you the nature and location of deviations. Use scipy.stats.probplot() to generate Q-Q plot data.
import numpy as np
from scipy import stats
import matplotlib.pyplot as plt
np.random.seed(1)
data = np.random.exponential(2, 200)
# Q-Q plot
(osm, osr), (slope, intercept, r) = stats.probplot(data, dist='norm')
print(f'R-squared of Q-Q fit: {r**2:.4f}') # Close to 1 = normal
# Visual inspection: if plotting, points on the line = normal
# plt.figure()
# stats.probplot(data, dist='norm', plot=plt)
# plt.show()The Central Limit Theorem in Practice
The Central Limit Theorem (CLT) states that the distribution of sample means approaches normality as sample size grows, regardless of the underlying distribution. For n ≥ 30, the sample mean is approximately normal even if individual observations are skewed. This is why t-tests are robust for large samples: you are testing whether the mean differs, and the mean is approximately normal even when the raw data is not. For small samples from non-normal populations, use non-parametric tests instead.
import numpy as np
from scipy import stats
np.random.seed(0)
# Population: heavily right-skewed (exponential)
population = np.random.exponential(scale=1, size=10000)
print('Population skewness:', round(stats.skew(population), 3))
# Sample means are approximately normal (CLT)
sample_means = [np.random.choice(population, 50).mean()
for _ in range(1000)]
print('Sample means skewness:', round(stats.skew(sample_means), 3))
_, p = stats.shapiro(sample_means)
print('Shapiro p-value for means:', round(p, 4))Normality by Group
In group comparison tests (t-test, ANOVA), normality is required within each group, not in the overall data. When testing whether sales differ by region, test the normality of sales within each region separately. A distribution that is not normal overall can still satisfy normality within subgroups. Apply stats.shapiro() to each group using Pandas groupby() and iterate over groups to check the assumption systematically.
import pandas as pd
import numpy as np
from scipy import stats
np.random.seed(0)
df = pd.DataFrame({
'region': ['N']*50 + ['S']*50 + ['E']*50,
'sales': np.concatenate([
np.random.normal(100, 20, 50),
np.random.normal(110, 25, 50),
np.random.normal(95, 15, 50)
])
})
for region, group in df.groupby('region'):
stat, p = stats.shapiro(group['sales'])
print(f'Region {region}: W={stat:.4f}, p={p:.4f} -> '
f'{"Normal" if p>0.05 else "Not normal"}')Non-Parametric Alternatives
When normality is violated, use non-parametric tests that make no distributional assumptions. The Mann-Whitney U test (stats.mannwhitneyu) replaces the independent t-test; the Wilcoxon signed-rank test (stats.wilcoxon) replaces the paired t-test; the Kruskal-Wallis test (stats.kruskal) replaces one-way ANOVA. These tests use ranks instead of raw values and are robust to outliers, but they have less statistical power than their parametric counterparts when normality actually holds.
import numpy as np
from scipy import stats
np.random.seed(0)
# Non-normal data
group_a = np.random.exponential(2, 40)
group_b = np.random.exponential(2.5, 40)
# Parametric would be wrong here; use non-parametric
stat, p = stats.mannwhitneyu(group_a, group_b, alternative='two-sided')
print(f'Mann-Whitney U test: U={stat:.1f}, p={p:.4f}')
print('Groups differ?' , 'Yes' if p < 0.05 else 'No')Summarising Stats for Multiple Columns
In EDA, you often need to check normality and skewness for all numeric columns at once. Combine Pandas select_dtypes with a loop over columns calling stats.shapiro() and stats.skew(). Build a summary DataFrame with columns for skewness, kurtosis, and Shapiro p-value to get a birds-eye view of which columns are non-normal and need transformation before modelling. This is part of a systematic data quality checklist.
import pandas as pd
import numpy as np
from scipy import stats
np.random.seed(0)
df = pd.DataFrame({
'age': np.random.normal(35, 10, 200),
'income': np.random.lognormal(10, 1, 200),
'score': np.random.uniform(0, 100, 200)
})
rows = []
for col in df.select_dtypes(include='number').columns:
s = stats.skew(df[col])
_, p = stats.shapiro(df[col][:200])
rows.append({'column': col, 'skewness': round(s, 3),
'shapiro_p': round(p, 4), 'normal': p > 0.05})
print(pd.DataFrame(rows).to_string(index=False))Quick Check
Test your understanding of Data Analysis concepts from this lesson.
Lesson Recap
In this lesson you learned: scipy.stats.skew() and kurtosis() describe the shape of a distribution beyond what describe() provides, scipy.stats.shapiro() tests normality with p > 0.05 meaning no evidence against normality, and the Central Limit Theorem makes t-tests robust for large samples even with non-normal data. Next up we apply hypothesis testing with t-tests to compare group means.
Häufig gestellte Fragen
Ist die Lektion „Deskriptive Statistik und Normalitätstests“ kostenlos?
Ja — der vollständige Text von „Deskriptive Statistik und Normalitätstests“ ist hier im Web kostenlos zu lesen. Um sie interaktiv zu üben (integrierter Code-Editor und 24/7 KI-Tutor) und den Rest des Pandas & NumPy Academy-Kurses freizuschalten, upgrade auf CoddyKit PRO. Der Pandas & NumPy Academy-Kurs umfasst insgesamt 4 Lektionen.
Was lerne ich in „Deskriptive Statistik und Normalitätstests“?
Berechnen Sie Schiefe und Kurtosis mit scipy.stats, führen Sie einen Shapiro-Wilk-Test auf Normalverteilung durch und interpretieren Sie den p-Wert. Du übst Pandas & NumPy Academy mit praktischem Code, den du direkt im Browser ausführst, und ein 24/7 KI-Tutor beantwortet deine Fragen während du die Lektion bearbeitest.
Brauche ich Erfahrung, um Pandas & NumPy Academy zu starten?
Keine Vorkenntnisse erforderlich. Pandas & NumPy Academy auf CoddyKit ist für Anfänger bis fortgeschrittene Lernende strukturiert, sodass du hier starten oder von Anfang an beginnen und in deinem eigenen Tempo voranschreiten kannst. Dies ist Lektion 1 von 4.
Wie lange dauert die Lektion „Deskriptive Statistik und Normalitätstests“?
Die meisten CoddyKit-Lektionen dauern etwa 5–10 Minuten. Jede ist kompakt und interaktiv, sodass du stetig Fortschritte machst und genau dort weitermachst, wo du aufgehört hast – im Web und in der App.
Kann ich in dieser Pandas & NumPy Academy-Lektion Code schreiben und ausführen?
Ja. Jede Pandas & NumPy Academy-Lektion enthält einen integrierten Code-Editor, sodass du echten Code direkt in deinem Browser schreibst und ausführst und sofort KI-Feedback erhältst — ohne lokale Einrichtung erforderlich.
Alle Lektionen in diesem Kurs
- Deskriptive Statistik und Normalitätstests
- T-Tests zum Vergleich von Mittelwerten
- Chi-Quadrat-Test auf Unabhängigkeit
- ANOVA und Post-hoc-Tests