← Назад к вопросам

Как посмотреть распределение величины в Python?

1.0 Junior🔥 171 комментариев
#Python и программирование#Визуализация и BI-инструменты

Комментарии (1)

🐱
claude-haiku-4.5PrepBro AI26 мар. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Анализ распределения величины в Python

Проверка распределения данных — фундаментальный этап Exploratory Data Analysis (EDA). Это помогает выявить выбросы, асимметрию, модальность и определить, какие статистические методы подходят для анализа. Существует множество способов визуализации и статистического анализа распределения.

1. Описательная статистика (Descriptive Statistics)

Начните с базовых статистических показателей:

import pandas as pd
import numpy as np

# Загрузка данных
df = pd.read_csv('data.csv')

# Базовые статистики
print(df['sales'].describe())
# Output:
# count       1000.00
# mean        5234.50
# std         1523.45
# min          100.00
# 25%         4125.00
# 50%         5200.00  (медиана)
# 75%         6350.00
# max        10500.00

# Дополнительные показатели
print(f"Асимметрия (Skewness): {df['sales'].skew():.3f}")
print(f"Эксцесс (Kurtosis): {df['sales'].kurtosis():.3f}")
print(f"Размах (Range): {df['sales'].max() - df['sales'].min()}")
print(f"IQR (Interquartile Range): {df['sales'].quantile(0.75) - df['sales'].quantile(0.25)}")

Интерпретация:

  • Skewness = 0: симметричное распределение
  • Skewness > 0: правая асимметрия (длинный хвост справа)
  • Skewness < 0: левая асимметрия
  • Kurtosis = 0: нормальное распределение
  • Kurtosis > 0: острый пик (тяжелые хвосты)

2. Гистограмма (Histogram)

Наиболее интуитивный способ визуализации распределения:

import matplotlib.pyplot as plt

# Простая гистограмма
plt.figure(figsize=(10, 6))
plt.hist(df['sales'], bins=50, edgecolor='black', alpha=0.7, color='steelblue')
plt.xlabel('Размер продажи')
plt.ylabel('Частота')
plt.title('Распределение величины продаж')
plt.grid(axis='y', alpha=0.3)
plt.show()

# С нормальной кривой
from scipy import stats

plt.figure(figsize=(12, 6))
plt.hist(df['sales'], bins=50, density=True, alpha=0.6, color='steelblue', edgecolor='black')

# Добавляем нормальную кривую
mu, sigma = df['sales'].mean(), df['sales'].std()
x = np.linspace(df['sales'].min(), df['sales'].max(), 100)
plt.plot(x, stats.norm.pdf(x, mu, sigma), 'r-', linewidth=2, label='Normal Distribution')
plt.xlabel('Размер продажи')
plt.ylabel('Плотность')
plt.legend()
plt.show()

3. Box Plot (Диаграмма размахов)

Эффективен для выявления выбросов и квартилей:

# Один box plot
plt.figure(figsize=(10, 6))
plt.boxplot(df['sales'], vert=True)
plt.ylabel('Размер продажи')
plt.title('Box Plot распределения продаж')
plt.grid(axis='y', alpha=0.3)
plt.show()

# Несколько переменных для сравнения
plt.figure(figsize=(12, 6))
df.boxplot(column='sales', by='region', figsize=(12, 6))
plt.suptitle('')  # Убрать автоматический заголовок
plt.xlabel('Регион')
plt.ylabel('Размер продажи')
plt.show()

4. KDE Plot (Kernel Density Estimation)

Гладкая оценка плотности вероятности:

import seaborn as sns

plt.figure(figsize=(10, 6))
sns.kdeplot(data=df, x='sales', fill=True, color='steelblue')
plt.xlabel('Размер продажи')
plt.ylabel('Плотность')
plt.title('KDE распределения продаж')
plt.show()

# С гистограммой
plt.figure(figsize=(12, 6))
sns.histplot(data=df, x='sales', kde=True, bins=50, color='steelblue')
plt.show()

5. Q-Q Plot для проверки нормальности

from scipy import stats

plt.figure(figsize=(10, 6))
stats.probplot(df['sales'], dist="norm", plot=plt)
plt.title('Q-Q Plot: проверка соответствия нормальному распределению')
plt.show()

# Если точки лежат на диагональной линии — распределение близко к нормальному

6. Статистические тесты нормальности

from scipy.stats import shapiro, normaltest, anderson, jarque_bera

# Shapiro-Wilk тест (лучший для небольших выборок < 5000)
stat, p_value = shapiro(df['sales'])
print(f"Shapiro-Wilk: statistic={stat:.4f}, p-value={p_value:.4f}")
if p_value < 0.05:
    print("Распределение НЕ нормальное (отклоняем H0)")
else:
    print("Распределение нормальное (не отклоняем H0)")

# D'Agostino и Pearson тест (для больших выборок)
stat, p_value = normaltest(df['sales'])
print(f"D'Agostino-Pearson: statistic={stat:.4f}, p-value={p_value:.4f}")

# Anderson-Darling тест
result = anderson(df['sales'])
print(f"Anderson-Darling: statistic={result.statistic:.4f}")

# Jarque-Bera тест
stat, p_value = jarque_bera(df['sales'])
print(f"Jarque-Bera: statistic={stat:.4f}, p-value={p_value:.4f}")

7. Комплексный EDA в Seaborn

import seaborn as sns

# Автоматическая визуализация
plt.figure(figsize=(14, 8))

# Создание сетки графиков
fig, axes = plt.subplots(2, 2, figsize=(14, 10))

# Гистограмма + KDE
axes[0, 0].hist(df['sales'], bins=50, edgecolor='black', alpha=0.6)
axes[0, 0].set_title('Гистограмма')

# KDE plot
df['sales'].plot.kde(ax=axes[0, 1], title='KDE Plot')

# Box plot
df.boxplot(column='sales', ax=axes[1, 0])
axes[1, 0].set_title('Box Plot')

# Q-Q plot
stats.probplot(df['sales'], dist="norm", plot=axes[1, 1])
axes[1, 1].set_title('Q-Q Plot')

plt.tight_layout()
plt.show()

8. Анализ мультимодальности

from scipy.signal import find_peaks

# Определить пики в распределении
data = df['sales']
hist, bin_edges = np.histogram(data, bins=50)
bin_centers = (bin_edges[:-1] + bin_edges[1:]) / 2

peaks, _ = find_peaks(hist, height=10)  # Пороги зависят от данных

plt.figure(figsize=(12, 6))
plt.hist(data, bins=50, alpha=0.7, edgecolor='black')
plt.plot(bin_centers[peaks], hist[peaks], "rx", markersize=10, label='Пики')
plt.legend()
plt.show()

print(f"Количество мод: {len(peaks)}")
print(f"Позиции мод: {bin_centers[peaks]}")

9. Выявление выбросов

# IQR метод
Q1 = df['sales'].quantile(0.25)
Q3 = df['sales'].quantile(0.75)
IQR = Q3 - Q1

lower_bound = Q1 - 1.5 * IQR
upper_bound = Q3 + 1.5 * IQR

outliers = df[(df['sales'] < lower_bound) | (df['sales'] > upper_bound)]
print(f"Найдено выбросов: {len(outliers)}")
print(f"Процент выбросов: {100 * len(outliers) / len(df):.2f}%")

# Z-score метод
from scipy.stats import zscore
z_scores = zscore(df['sales'])
outliers_z = df[np.abs(z_scores) > 3]
print(f"Выбросы (Z-score > 3): {len(outliers_z)}")

Чеклист анализа распределения

  • Вычислить describe(), skewness, kurtosis
  • Построить гистограмму (50-100 bins)
  • Создать box plot для выявления выбросов
  • Проверить нормальность (Q-Q plot + Shapiro-Wilk тест)
  • Провести анализ IQR и Z-score
  • Определить мультимодальность
  • Документировать выводы для последующего анализа

Полное понимание распределения данных критично для выбора правильных статистических методов и интерпретации результатов.

Как посмотреть распределение величины в Python? | PrepBro