Histogram в Pandas: создание и анализ гистограмм для данных

Пройдите тест, узнайте какой профессии подходите
Сколько вам лет
0%
До 18
От 18 до 24
От 25 до 34
От 35 до 44
От 45 до 49
От 50 до 54
Больше 55

Для кого эта статья:

  • аналитики данных и статистики
  • обучающиеся на курсах аналитики данных
  • специалисты, заинтересованные в визуализации данных и использовании библиотеки Pandas

    Когда массивы данных превращаются в неприступную стену цифр, гистограммы становятся вашим тайным оружием визуализации. Анализируя распределение значений одним взглядом, вы мгновенно выявляете закономерности, которые таблицы скрывают годами. 📊 Библиотека Pandas превратила создание этих мощных инструментов в дело нескольких строк кода, но правильная настройка и интерпретация результатов — вот где начинается настоящее искусство аналитики данных. Давайте разберемся, как превратить хаос числовых данных в наглядные гистограммы, раскрывающие истинную суть вашего датасета.

Устали от бесконечных таблиц и не можете решить, как эффективнее визуализировать данные? На Курсе «Аналитик данных» с нуля от Skypro вы научитесь создавать идеально настроенные гистограммы и другие виды визуализации в Pandas. Опытные эксперты покажут не только механизмы создания графиков, но и профессиональные приёмы их интерпретации, позволяющие принимать точные бизнес-решения. Переходите от текстовых таблиц к наглядным инсайтам уже через 6 месяцев обучения.

Что такое гистограммы и зачем они нужны в Pandas

Гистограмма — это графическое представление распределения числовых данных, где значения группируются в интервалы (бины), а высота столбцов отражает частоту или количество наблюдений в каждом интервале. По сути, это бар-чарт, который показывает плотность распределения данных.

В мире анализа данных гистограммы решают сразу несколько критических задач:

  • Мгновенная оценка формы распределения (нормальное, скошенное, бимодальное)
  • Выявление выбросов и аномалий в данных
  • Определение центральной тенденции и разброса значений
  • Проверка гипотез о распределении данных
  • Сравнение распределений разных наборов данных

Библиотека Pandas делает создание гистограмм элементарным, интегрируя функциональность matplotlib с удобными методами DataFrame и Series. Это позволяет аналитикам быстро переходить от сырых данных к их визуальному исследованию.

Задача анализа Что показывает гистограмма Преимущество использования в Pandas
Распределение признака Форму, модальность, асимметрию Встроенные методы без сложной настройки
Выявление выбросов Изолированные столбцы вдали от основного распределения Автоматическое масштабирование осей
Проверка нормальности Колоколообразную форму (или её отсутствие) Возможность наложения теоретических распределений
Сравнение групп Различия в распределениях между подгруппами Лёгкость создания множественных гистограмм

Михаил Бернштейн, старший аналитик данных

Однажды мне поручили выяснить, почему новая модель прогнозирования спроса давала странные результаты для определенного региона. Таблицы с миллионами строк не давали никаких подсказок. Я создал гистограмму распределения заказов с помощью простого кода:

Python
Скопировать код
import pandas as pd
import matplotlib.pyplot as plt

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

# Построение гистограммы
orders_df['order_amount'].hist(bins=50)
plt.title('Распределение объемов заказов')
plt.xlabel('Объем заказа, руб.')
plt.ylabel('Количество заказов')
plt.show()

Гистограмма мгновенно выявила бимодальное распределение — два пика вместо ожидаемого одного. Оказалось, что в данных смешались заказы частных лиц и корпоративных клиентов с совершенно разными паттернами потребления. Разделив эти сегменты и построив отдельные модели, мы повысили точность прогнозов на 37%. Один график сэкономил недели работы.

Пошаговый план для смены профессии

Базовые методы создания гистограмм в Pandas

Pandas предлагает несколько элегантных способов создания гистограмм, адаптированных под различные сценарии анализа. Освоение этих базовых методов — первый шаг к мастерству визуализации данных. 📈

Самый простой способ создать гистограмму — использовать метод hist(), который доступен как для объектов Series, так и для DataFrame:

Python
Скопировать код
# Для Series
df['column_name'].hist()

# Для всех числовых колонок DataFrame
df.hist()

Рассмотрим ключевые методы создания гистограмм в Pandas:

  • Series.hist() — создает гистограмму для одного столбца данных
  • DataFrame.hist() — генерирует сетку гистограмм для всех числовых столбцов
  • DataFrame.plot.hist() — альтернативный интерфейс с дополнительными опциями
  • pandas.plotting.hist_series() — низкоуровневая функция с расширенным контролем

Приведем пример комплексного использования этих методов:

Python
Скопировать код
import pandas as pd
import matplotlib.pyplot as plt

# Создаем тестовый DataFrame
df = pd.DataFrame({
'рост': np.random.normal(170, 10, 1000),
'вес': np.random.normal(70, 15, 1000),
'возраст': np.random.normal(35, 8, 1000)
})

# Метод 1: Гистограмма одного столбца
df['рост'].hist(bins=20, color='skyblue', edgecolor='black')
plt.title('Распределение роста')
plt.show()

# Метод 2: Гистограммы всех числовых столбцов
df.hist(figsize=(12, 4), bins=15, color='lightgreen', 
grid=False, layout=(1, 3))
plt.tight_layout()
plt.show()

# Метод 3: Использование plot.hist()
df.plot.hist(alpha=0.7, bins=20, subplots=True, 
layout=(3, 1), figsize=(10, 8))
plt.show()

Каждый из этих методов имеет свои нюансы и преимущества в зависимости от задачи:

Метод Сценарий использования Особенности
Series.hist() Анализ одиночной переменной Лаконичный код, быстрое исследование
DataFrame.hist() Сравнение нескольких переменных Автоматическая компоновка нескольких графиков
DataFrame.plot.hist() Презентационные графики Расширенные возможности стилизации
pandas.plotting.hist_series() Специализированные гистограммы Наибольший контроль над графиком

При работе с большими наборами данных важно учитывать производительность. Для датасетов объемом более миллиона записей рекомендуется использовать параметр bins='auto' и метод plot.hist(), который эффективнее обрабатывает большие массивы.

Настройка параметров гистограмм для точного анализа

Настройка параметров гистограммы определяет, насколько точно график отражает истинное распределение данных. Правильно настроенная гистограмма — это разница между обнаружением ключевого инсайта и пропуском важной закономерности. 🔍

Самым критичным параметром является количество интервалов (bins). Слишком мало — и вы потеряете детали распределения; слишком много — и график станет зашумленным:

Python
Скопировать код
# Сравнение различного количества bins
fig, axes = plt.subplots(1, 3, figsize=(15, 4))

df['доход'].hist(bins=5, ax=axes[0], color='coral')
axes[0].set_title('5 интервалов (слишком мало)')

df['доход'].hist(bins=20, ax=axes[1], color='lightblue')
axes[1].set_title('20 интервалов (оптимально)')

df['доход'].hist(bins=100, ax=axes[2], color='lightgreen')
axes[2].set_title('100 интервалов (слишком много)')

plt.tight_layout()

Рассмотрим ключевые параметры для настройки гистограмм в Pandas:

  • bins — количество интервалов или их границы в виде списка
  • range — ограничение диапазона данных (мин, макс)
  • density — нормализация гистограммы для получения плотности вероятности
  • cumulative — построение кумулятивной гистограммы
  • alpha — прозрачность столбцов (полезно при наложении гистограмм)
  • grid — отображение сетки для улучшения восприятия
  • figsize — размер графика в дюймах

Рассмотрим пример тонкой настройки гистограммы для анализа асимметричных данных:

Python
Скопировать код
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt

# Создаем асимметричные данные (например, доходы населения)
skewed_data = np.random.lognormal(mean=8, sigma=1, size=10000)
df = pd.DataFrame({'доход': skewed_data})

# Создаем оптимизированную гистограмму
plt.figure(figsize=(10, 6))
df['доход'].hist(
bins=40, # Оптимальное количество интервалов
color='skyblue', # Цвет столбцов
alpha=0.8, # Полупрозрачность
density=True, # Нормализация по площади
edgecolor='white', # Границы столбцов
range=(0, 30000) # Обрезаем экстремальные выбросы
)

# Добавляем линию плотности вероятности для сравнения
df['доход'].plot(kind='kde', color='darkblue', linewidth=2)

plt.title('Распределение доходов населения', fontsize=14)
plt.xlabel('Доход, тыс. руб.', fontsize=12)
plt.ylabel('Плотность', fontsize=12)
plt.grid(axis='y', alpha=0.3)
plt.tight_layout()
plt.show()

Для определения оптимального числа интервалов существуют различные методы:

Правило Формула Случаи применения
Правило Стерджеса 1 + log₂(n) Для нормального распределения
Правило Фридмана-Диакониса 2 × IQR × n⁻⅓ Устойчиво к выбросам
Правило Скотта 3.5 × σ × n⁻⅓ Для приближенно нормального распределения
Квадратный корень √n Простое эмпирическое правило

В Pandas можно использовать эти правила, указав соответствующее строковое значение в параметре bins:

Python
Скопировать код
# Автоматический подбор количества интервалов
df['column'].hist(bins='auto') # Правило Фридмана-Диакониса
df['column'].hist(bins='sturges') # Правило Стерджеса
df['column'].hist(bins='scott') # Правило Скотта
df['column'].hist(bins='fd') # Синоним Фридмана-Диакониса

Интерпретация гистограмм: что показывают распределения

Анна Ковалева, руководитель аналитического отдела

В прошлом году мы запустили программу оптимизации времени доставки наших товаров. Мой коллега уверял всех, что среднее время доставки снизилось на 15% после внедрения новой логистической системы. Но клиенты продолжали жаловаться.

Я построила гистограммы времени доставки "до" и "после":

Python
Скопировать код
# Построение наложенных гистограмм
fig, ax = plt.subplots(figsize=(10, 6))
before_df['delivery_time'].hist(alpha=0.5, bins=30, label='До оптимизации', ax=ax)
after_df['delivery_time'].hist(alpha=0.5, bins=30, label='После оптимизации', ax=ax)
ax.set_xlabel('Время доставки (часы)')
ax.set_ylabel('Количество заказов')
ax.legend()
plt.show()

Гистограмма раскрыла истину: среднее действительно снизилось, но из-за бимодального распределения. Новая система ускорила доставку в центральные районы (первый пик), но периферийные районы (второй пик) стали обслуживаться даже медленнее. Вдобавок появился "длинный хвост" экстремально долгих доставок.

Инсайт позволил нам перенастроить логистику для периферийных зон и добиться реального улучшения, подтвержденного гистограммой с нормальным распределением и без "хвостов".

Гистограмма — это намного больше, чем просто набор столбцов. Её форма рассказывает удивительно детальную историю о распределении ваших данных. 📝 Умение " читать" гистограммы превращает аналитика из простого технического специалиста в стратега, способного выявлять неочевидные закономерности.

Основные характеристики распределений, видимые на гистограммах:

  • Центральная тенденция — где сосредоточена масса данных
  • Разброс — насколько широко разбросаны значения
  • Форма — симметричная, скошенная, многомодальная
  • Выбросы — изолированные значения вне основного распределения
  • Пробелы — отсутствующие значения в определенных диапазонах

Давайте рассмотрим основные типы распределений, которые вы можете встретить на практике:

Тип распределения Как выглядит на гистограмме Интерпретация и применение
Нормальное (Гауссово) Колоколообразная симметричная форма Естественные процессы, многие биологические параметры
Правосторонняя асимметрия Пик слева, "хвост" справа Доходы, цены, время ожидания
Левосторонняя асимметрия Пик справа, "хвост" слева Возраст смерти, результаты тестов с "потолком"
Бимодальное Два отчетливых пика Смесь двух групп, например, возрасты учеников и учителей
Равномерное Примерно одинаковая высота всех столбцов Случайные процессы, округленные данные
Мультимодальное Несколько пиков Несколько подгрупп в данных

Для эффективной интерпретации гистограмм в Pandas можно использовать дополнительные элементы:

Python
Скопировать код
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
from scipy import stats

# Создаем смесь двух нормальных распределений
group1 = np.random.normal(loc=5, scale=1, size=1000)
group2 = np.random.normal(loc=10, scale=1.5, size=1000)
mixed_data = np.concatenate([group1, group2])

df = pd.DataFrame({'значения': mixed_data})

# Создаем гистограмму с дополнительными элементами
plt.figure(figsize=(12, 6))

# Основная гистограмма
n, bins, patches = plt.hist(df['значения'], bins=40, 
alpha=0.7, color='skyblue', 
density=True, edgecolor='white')

# Добавляем линию плотности вероятности
x = np.linspace(df['значения'].min(), df['значения'].max(), 100)
kde = stats.gaussian_kde(df['значения'])
plt.plot(x, kde(x), 'r-', linewidth=2, label='KDE')

# Добавляем вертикальные линии для статистических показателей
plt.axvline(df['значения'].mean(), color='red', linestyle='dashed', 
linewidth=2, label=f'Среднее: {df["значения"].mean():.2f}')
plt.axvline(df['значения'].median(), color='green', linestyle='dashed', 
linewidth=2, label=f'Медиана: {df["значения"].median():.2f}')
plt.axvline(df['значения'].mode().iloc[0], color='purple', linestyle='dashed', 
linewidth=2, label=f'Мода: {df["значения"].mode().iloc[0]:.2f}')

# Добавляем аннотации и оформление
plt.title('Интерпретация бимодального распределения', fontsize=14)
plt.xlabel('Значение', fontsize=12)
plt.ylabel('Плотность вероятности', fontsize=12)
plt.legend()
plt.grid(alpha=0.3)
plt.tight_layout()
plt.show()

При интерпретации гистограмм важно учитывать контекст данных и избегать типичных ошибок:

  • Не путать частоту с важностью — высокий столбец не всегда означает важный сегмент
  • Учитывать влияние выбросов на среднее — при асимметричных распределениях медиана информативнее
  • Помнить о "ложных бимодальностях" из-за неоптимального числа bins
  • Сочетать анализ гистограмм с формальными статистическими тестами
  • Быть осторожным с интерпретацией "хвостов" распределения, где число наблюдений мало

Определились с направлением в аналитике данных после изучения гистограмм? Тест на профориентацию от Skypro поможет выяснить, какая специализация в анализе данных подойдет именно вам. Выясните, стоит ли вам погружаться в статистический анализ, визуализацию данных или машинное обучение всего за 5 минут. Получите персональные рекомендации по развитию навыков работы с данными, основанные на вашем опыте, интересах и способностях.

Продвинутые техники работы с гистограмmmi в Pandas

Освоив базовые методы, пора перейти к продвинутым техникам, которые превратят ваши гистограммы из простых диаграмм в мощные инструменты анализа. 🚀 Эти методы позволяют глубже погрузиться в данные и извлечь максимум информации из распределений.

Рассмотрим несколько продвинутых техник:

  1. Наложение нескольких гистограмм для сравнения распределений
  2. Комбинирование с другими визуализациями (box plot, violin plot)
  3. Условные гистограммы для анализа подгрупп
  4. Логарифмические преобразования для работы с данными большого диапазона
  5. Интеграция статистических тестов с визуализацией

Давайте рассмотрим пример продвинутой техники — наложение нескольких гистограмм с полупрозрачностью для сравнения:

Python
Скопировать код
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.ticker import PercentFormatter

# Создаем DataFrame с данными о скорости загрузки страниц в разных браузерах
np.random.seed(42)
data = {
'Chrome': np.random.gamma(shape=2, scale=0.5, size=1000),
'Firefox': np.random.gamma(shape=2.2, scale=0.6, size=1000),
'Safari': np.random.gamma(shape=1.8, scale=0.7, size=1000)
}
df = pd.DataFrame(data)

# Создаем гистограммы с наложением
plt.figure(figsize=(12, 7))

# Общие параметры для всех гистограмм
params = dict(
alpha=0.5, # Полупрозрачность для наложения
bins=30, # Одинаковое количество бинов
density=True, # Нормализация площади
histtype='stepfilled', # Тип гистограммы с заливкой
)

# Строим гистограммы для каждого браузера
browsers = ['Chrome', 'Firefox', 'Safari']
colors = ['#4285F4', '#FF9800', '#34A853']

for browser, color in zip(browsers, colors):
df[browser].hist(label=browser, color=color, **params)

# Оформляем график
plt.title('Сравнение времени загрузки страниц в разных браузерах', fontsize=15)
plt.xlabel('Время загрузки (секунды)', fontsize=12)
plt.ylabel('Плотность вероятности', fontsize=12)
plt.grid(alpha=0.3)
plt.legend(title='Браузер')

# Добавляем вертикальные линии средних значений
for browser, color in zip(browsers, colors):
plt.axvline(df[browser].mean(), color=color, linestyle='--', 
linewidth=2, label=f'_Среднее {browser}')

plt.tight_layout()
plt.show()

Еще одна мощная техника — создание 2D-гистограмм для анализа взаимосвязей между двумя числовыми переменными:

Python
Скопировать код
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt

# Создаем данные для 2D-гистограммы
mean = [0, 0]
cov = [[1, 0.5], [0\.5, 1]]
x, y = np.random.multivariate_normal(mean, cov, 10000).T
df = pd.DataFrame({'x': x, 'y': y})

# Создаем 2D-гистограмму
plt.figure(figsize=(10, 8))
plt.hist2d(df['x'], df['y'], bins=50, cmap='viridis')
plt.colorbar(label='Частота')
plt.title('2D-гистограмма корреляции переменных', fontsize=14)
plt.xlabel('Переменная X', fontsize=12)
plt.ylabel('Переменная Y', fontsize=12)
plt.tight_layout()
plt.show()

Для более сложных сценариев анализа можно использовать сочетание гистограмм с другими типами визуализаций:

Python
Скопировать код
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns

# Создаем синтетические данные с группами
np.random.seed(42)
n = 1000
groups = ['Группа A', 'Группа B', 'Группа C']
data = {
'значение': np.concatenate([
np.random.normal(5, 1, n), 
np.random.normal(6, 1.5, n), 
np.random.normal(4, 2, n)
]),
'группа': np.repeat(groups, n)
}
df = pd.DataFrame(data)

# Создаем комбинированную визуализацию
plt.figure(figsize=(14, 10))

# 1. Общая гистограмма
plt.subplot(2, 2, 1)
sns.histplot(data=df, x='значение', kde=True)
plt.title('Общая гистограмма')

# 2. Гистограммы по группам
plt.subplot(2, 2, 2)
sns.histplot(data=df, x='значение', hue='группа', 
element='step', common_norm=False)
plt.title('Гистограммы по группам')

# 3. Box plot для сравнения
plt.subplot(2, 2, 3)
sns.boxplot(data=df, x='группа', y='значение')
plt.title('Box Plot по группам')

# 4. Violin plot для распределений
plt.subplot(2, 2, 4)
sns.violinplot(data=df, x='группа', y='значение', inner='quartile')
plt.title('Violin Plot по группам')

plt.tight_layout()
plt.show()

Интерактивные гистограммы с использованием библиотеки Plotly позволяют исследовать данные более детально:

Python
Скопировать код
import pandas as pd
import numpy as np
import plotly.express as px

# Создаем данные
np.random.seed(42)
df = pd.DataFrame({
'категория': np.repeat(['A', 'B', 'C'], 1000),
'значение': np.concatenate([
np.random.normal(0, 1, 1000), 
np.random.normal(3, 2, 1000), 
np.random.normal(-2, 1.5, 1000)
])
})

# Создаем интерактивную гистограмму
fig = px.histogram(
df, x='значение', color='категория',
marginal='box', # Добавляем box plot на полях
opacity=0.7, # Прозрачность для наложения
barmode='overlay', # Режим наложения
histnorm='probability density', # Нормализация
hover_data=df.columns # Данные при наведении
)

# Настраиваем внешний вид
fig.update_layout(
title='Интерактивная гистограмма с группировкой',
xaxis_title='Значение переменной',
yaxis_title='Плотность',
legend_title='Категория'
)

fig.show()

Использование условных гистограмм в сочетании с другими статистиками позволяет проводить более глубокий анализ данных:

Python
Скопировать код
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
from scipy import stats

# Создаем DataFrame с данными о доходе по регионам
regions = ['Север', 'Юг', 'Запад', 'Восток']
data = {}
np.random.seed(42)

for region in regions:
if region == 'Север':
data[region] = np.random.lognormal(mean=10, sigma=0.4, size=1000)
elif region == 'Юг':
data[region] = np.random.lognormal(mean=9.8, sigma=0.5, size=1000)
elif region == 'Запад':
data[region] = np.random.lognormal(mean=10.2, sigma=0.3, size=1000)
else: # Восток
data[region] = np.random.lognormal(mean=10.1, sigma=0.6, size=1000)

# Подготавливаем данные для анализа
df_income = pd.DataFrame(data)
df_melted = df_income.melt(var_name='region', value_name='income')

# Создаем фигуру с несколькими подграфиками
fig, axes = plt.subplots(2, 2, figsize=(15, 12))
axes = axes.flatten()

# Статистические данные для аннотаций
stats_data = {}
for i, region in enumerate(regions):
# Рассчитываем статистики
mean_val = df_income[region].mean()
median_val = df_income[region].median()
skew_val = stats.skew(df_income[region])
kurtosis_val = stats.kurtosis(df_income[region])

stats_data[region] = {
'mean': mean_val,
'median': median_val,
'skewness': skew_val,
'kurtosis': kurtosis_val
}

# Строим гистограмму
df_income[region].hist(bins=30, alpha=0.7, ax=axes[i], 
density=True, color=f'C{i}')

# Добавляем KDE
x = np.linspace(df_income[region].min(), df_income[region].max(), 100)
axes[i].plot(x, stats.kde.gaussian_kde(df_income[region])(x), 
'r-', linewidth=2)

# Добавляем вертикальные линии для среднего и медианы
axes[i].axvline(mean_val, color='red', linestyle='-', 
label=f'Среднее: {mean_val:.0f}')
axes[i].axvline(median_val, color='green', linestyle='-', 
label=f'Медиана: {median_val:.0f}')

# Добавляем статистические аннотации
stats_text = (f'Асимметрия: {skew_val:.2f}\n'
f'Эксцесс: {kurtosis_val:.2f}')
axes[i].text(0.95, 0.95, stats_text, transform=axes[i].transAxes,
verticalalignment='top', horizontalalignment='right',
bbox=dict(boxstyle='round', facecolor='white', alpha=0.7))

axes[i].set_title(f'Распределение дохода: {region}')
axes[i].set_xlabel('Доход')
axes[i].set_ylabel('Плотность')
axes[i].legend()
axes[i].grid(alpha=0.3)

plt.tight_layout()
plt.show()

Гистограммы в Pandas — это не просто способ показать распределение данных, а мощный инструмент принятия стратегических решений. Мы рассмотрели все аспекты их создания и интерпретации: от базового синтаксиса до продвинутых техник наложения и комбинирования с другими визуализациями. Правильное понимание формы распределения — ключ к выявлению скрытых закономерностей, определению аномалий и проверке статистических гипотез. Помните: эффективная визуализация превращает тысячи строк данных в ясное понимание происходящего, а это уже половина успеха в современной аналитике.

Загрузка...