Pandas Value Counts: быстрый анализ и подсчет уникальных значений
Пройдите тест, узнайте какой профессии подходите
Для кого эта статья:
- профессиональные аналитики данных
- студенты и начинающие специалисты в области анализа данных
практикующие разработчики и исследователи в области машинного обучения
Когда имеешь дело с гигабайтами данных, ключевой задачей становится быстро понять, из чего состоит твой датасет. Именно здесь на сцену выходит метод
value_counts()
— настоящий швейцарский нож в арсенале каждого профессионального аналитика данных. Этот компактный, но мощный инструмент библиотеки Pandas позволяет одной строкой кода увидеть частотное распределение категориальных переменных, обнаружить выбросы и несбалансированность классов. При правильном использованииvalue_counts()
может сэкономить часы аналитической работы и стать незаменимым помощником при подготовке данных для машинного обучения. 📊
Хотите превратить строки кода в конкретные бизнес-решения? Курс «Аналитик данных» с нуля от Skypro научит вас не просто механически применять функции вроде
value_counts()
, а глубоко понимать данные. Вместо бесконечных теоретических лекций — 70% практики на реальных кейсах. Под руководством опытных аналитиков из OZON, VK и других топовых компаний вы научитесь извлекать истинную ценность из сырых данных и формировать инсайты, которые впечатлят любого работодателя.
Что такое Pandas Value Counts: назначение и возможности
Value_counts()
— это метод библиотеки Pandas, который подсчитывает количество уникальных значений в Series (одномерный массив) или в конкретном столбце DataFrame. По сути, это элегантный способ получить частотное распределение данных одной командой, не прибегая к сложным группировкам или циклам.
Метод value_counts()
помогает решить следующие задачи:
- Быстро получить представление о распределении категориальных данных
- Обнаружить несбалансированность классов при подготовке моделей ML
- Найти выбросы и аномальные значения
- Оценить качество данных и выявить пропущенные значения
- Проверить корректность данных после трансформаций
Давайте сравним value_counts()
с другими методами подсчета уникальных значений:
Метод | Преимущества | Недостатки | Производительность |
---|---|---|---|
value_counts() | Одна строка кода, автоматическая сортировка, работа с NaN | Ограничен работой только с Series | Высокая |
groupby().count() | Более гибкий, позволяет группировать по нескольким столбцам | Требует больше кода, сложнее в использовании | Средняя |
Counter из collections | Может работать с любыми итерируемыми объектами | Неоптимизирован для pandas, требует преобразований | Низкая для больших данных |
nunique() | Моментально показывает количество уникальных значений | Не показывает распределение, только количество | Очень высокая |
Алексей Петров, Lead Data Scientist
Помню случай, когда мне пришлось анализировать огромный лог транзакций в финтех-компании. Размер файла — более 30 ГБ, миллионы записей. Цель была найти подозрительные паттерны, указывающие на возможное мошенничество. Вместо того чтобы сразу писать сложные запросы или разрабатывать ML-модели, я начал с простого — применил value_counts()
к столбцам с ID пользователей и типами транзакций.
Буквально за пару минут обнаружил, что несколько аккаунтов генерируют аномально высокое количество микротранзакций в определенное время суток. Дальнейшее расследование подтвердило: это была продуманная схема обхода системы безопасности. Если бы я сразу погрузился в сложный анализ, потребовались бы часы или даже дни, чтобы выявить эту аномалию. Value_counts()
сэкономил компании время и деньги.

Синтаксис и базовые параметры функции value_counts()
Функция value_counts()
имеет простой, но гибкий синтаксис, который позволяет настроить подсчет уникальных значений под ваши конкретные потребности. Базовый вызов выглядит следующим образом:
import pandas as pd
# Создаем простой Series
s = pd.Series(['A', 'B', 'A', 'C', 'B', 'A', None, 'D'])
# Применяем метод value_counts()
counts = s.value_counts()
print(counts)
# Результат:
# A 3
# B 2
# C 1
# D 1
# dtype: int64
Однако настоящая мощь value_counts()
раскрывается через его параметры, позволяющие тонко настраивать анализ данных. Рассмотрим основные из них:
Параметр | Описание | Значение по умолчанию | Пример применения |
---|---|---|---|
normalize | Возвращает относительные частоты вместо абсолютных | False | s.value_counts(normalize=True) |
sort | Сортировка результатов по частоте | True | s.value_counts(sort=False) |
ascending | Сортировка по возрастанию вместо убывания | False | s.value_counts(ascending=True) |
dropna | Исключение NaN значений из подсчета | True | s.value_counts(dropna=False) |
bins | Группировка числовых данных по интервалам | None | pd.Series([1, 2, 3, 4]).value_counts(bins=2) |
Рассмотрим практические примеры использования этих параметров:
# Получение относительных частот (доли вместо абсолютных значений)
s.value_counts(normalize=True)
# A 0.428571
# B 0.285714
# C 0.142857
# D 0.142857
# dtype: float64
# Включение пропущенных значений в подсчет
s.value_counts(dropna=False)
# A 3
# B 2
# C 1
# D 1
# NaN 1
# dtype: int64
# Бинирование числовых данных
numbers = pd.Series([1, 2, 5, 7, 8, 12, 15, 18, 19])
numbers.value_counts(bins=4)
# (0.971, 5.5] 2
# (5.5, 10.0] 3
# (10.0, 14.5] 1
# (14.5, 19.0] 3
# dtype: int64
Важно помнить, что value_counts()
возвращает Series с уникальными значениями в индексе и их количествами в значениях. Это позволяет легко интегрировать результаты с другими методами работы с Series для дальнейшего анализа. 🔍
Продвинутые техники использования Pandas Value Counts
После освоения базовых операций с value_counts()
пора погрузиться в более сложные техники, которые поднимут ваш анализ данных на новый уровень. Эти приемы особенно ценны при работе с большими и сложными датасетами, где простой подсчет — лишь начало анализа.
Комбинирование с другими методами Pandas
Value_counts()
раскрывает свой потенциал при комбинировании с другими функциями pandas:
# Создаем DataFrame с данными о клиентах
df = pd.DataFrame({
'customer_id': [1, 2, 3, 4, 5, 6, 7, 8],
'country': ['USA', 'Canada', 'USA', 'UK', 'USA', 'Canada', 'Germany', 'UK'],
'purchase_amount': [150, 200, 50, 300, 125, 175, 220, 90]
})
# 1. Применение value_counts() к результату запроса
# Найдем количество клиентов по странам, потративших больше 100
high_spenders = df[df['purchase_amount'] > 100]['country'].value_counts()
print(high_spenders)
# USA 2
# Canada 2
# UK 1
# Germany 1
# dtype: int64
# 2. Множественные группировки с pivot_table и value_counts()
# Группируем по странам и подсчитываем средний чек + количество клиентов
country_stats = pd.DataFrame({
'avg_purchase': df.groupby('country')['purchase_amount'].mean(),
'customer_count': df['country'].value_counts()
})
print(country_stats)
# avg_purchase customer_count
# Canada 187.5 2
# Germany 220.0 1
# UK 195.0 2
# USA 108.3 3
Условный подсчет и фильтрация
Иногда нужно подсчитать значения, соответствующие определенным критериям или выполнить фильтрацию после подсчета:
# Подсчет с фильтрацией результатов
# Показать только страны с более чем 1 клиентом
popular_countries = df['country'].value_counts()
popular_countries = popular_countries[popular_countries > 1]
print(popular_countries)
# USA 3
# Canada 2
# UK 2
# dtype: int64
# Применение лямбда-функций к value_counts()
# Найти процентное соотношение клиентов по странам
percentage = df['country'].value_counts().apply(lambda x: f"{(x/len(df)*100):.1f}%")
print(percentage)
# USA 37.5%
# Canada 25.0%
# UK 25.0%
# Germany 12.5%
# dtype: object
Многоуровневый анализ с value_counts()
Для более глубокого анализа можно комбинировать несколько столбцов в многоуровневый индекс:
# Добавим категорию продукта
df['product_category'] = ['Electronics', 'Clothing', 'Electronics',
'Home', 'Clothing', 'Electronics', 'Home', 'Clothing']
# Многоуровневый анализ: страна + категория продукта
# Сначала создадим мультииндекс
df['combined'] = df['country'] + '_' + df['product_category']
# Затем применим value_counts()
distribution = df['combined'].value_counts()
print(distribution)
# USA_Electronics 2
# Canada_Electronics 1
# USA_Clothing 1
# UK_Home 1
# UK_Clothing 1
# Germany_Home 1
# Canada_Clothing 1
# dtype: int64
Мария Соколова, Data Analytics Lead
Недавно наша команда столкнулась с задачей оптимизации рекламных кампаний для крупного маркетплейса. Бюджеты уходили в никуда, а конверсия оставалась низкой. Мы получили 3 ТБ необработанных логов — все клики, показы и переходы за последний квартал.
Первое, что я сделала — применила цепочку value_counts()
с различными параметрами для сегментации данных. Мы буквально за час выяснили, что 72% бюджета тратится на категорию пользователей, которая даёт только 8% конверсий. Эта находка казалась невероятной, поэтому мы углубились в данные, используя продвинутые техники value_counts()
с группировками по нескольким параметрам.
Оказалось, проблема была в узком сегменте пользователей, которые массово кликали на рекламу, но никогда не совершали покупки. Их поведение было настолько "правдоподобным", что алгоритмы не распознавали это как мошенничество. Перенастройка таргетинга сэкономила клиенту более миллиона рублей ежемесячно, а конверсия выросла на 34%. Всё благодаря правильному использованию, казалось бы, простой функции value_counts()
.
Продвинутое использование value_counts()
также включает в себя создание собственных функций-обёрток, которые расширяют базовый функционал для специфических задач анализа данных. Например, можно создать функцию, которая автоматически визуализирует результаты подсчёта редких категорий, группируя их в категорию "Другое". 📈
Визуализация результатов подсчета с помощью Value Counts
Числа и таблицы — мощный инструмент, но визуализация результатов value_counts()
позволяет моментально выявлять паттерны и тренды, которые могут ускользать при анализе сухих цифр. Pandas предоставляет встроенные возможности для быстрой визуализации результатов подсчета, а интеграция с другими библиотеками открывает по-настоящему широкие возможности. ✨
Базовая визуализация с matplotlib
Самый простой способ визуализировать результаты value_counts()
— использовать встроенный метод plot()
:
import pandas as pd
import matplotlib.pyplot as plt
# Создаем Series с данными
fruits = pd.Series(['apple', 'banana', 'apple', 'orange', 'apple',
'banana', 'grape', 'apple', 'orange'])
# Визуализируем результаты подсчета
fruits.value_counts().plot(kind='bar')
plt.title('Частота фруктов в датасете')
plt.ylabel('Количество')
plt.xlabel('Фрукты')
plt.xticks(rotation=45)
plt.tight_layout()
plt.show()
# Круговая диаграмма для отображения пропорций
fruits.value_counts().plot(kind='pie', autopct='%1.1f%%')
plt.title('Доля каждого фрукта в датасете')
plt.ylabel('') # Убираем метку для оси Y
plt.tight_layout()
plt.show()
Продвинутая визуализация с seaborn
Для более сложной и эстетически привлекательной визуализации отлично подходит библиотека seaborn:
import seaborn as sns
# Преобразуем результаты value_counts() в DataFrame для seaborn
count_df = pd.DataFrame({'fruit': fruits.value_counts().index,
'count': fruits.value_counts().values})
# Создаем горизонтальную гистограмму с цветовым градиентом
plt.figure(figsize=(10, 6))
ax = sns.barplot(x='count', y='fruit', data=count_df,
palette='viridis')
# Добавляем значения на график
for i, v in enumerate(count_df['count']):
ax.text(v + 0.1, i, str(v), va='center')
plt.title('Частота фруктов (Seaborn)', fontsize=15)
plt.tight_layout()
plt.show()
# Используем catplot для более сложных отношений
# Сначала создадим более богатый датасет
df = pd.DataFrame({
'fruit': fruits,
'quality': ['high', 'low', 'medium', 'high', 'medium',
'high', 'low', 'medium', 'high'],
'price': [5, 3, 4, 6, 5, 3, 2, 4, 5]
})
# Подсчитываем частоту комбинаций фрукт-качество
fruit_quality_counts = df.groupby(['fruit', 'quality']).size().reset_index(name='count')
# Создаем сгруппированную гистограмму
sns.catplot(x='fruit', y='count', hue='quality', data=fruit_quality_counts,
kind='bar', height=6, aspect=1.5)
plt.title('Распределение фруктов по качеству')
plt.tight_layout()
plt.show()
Интерактивная визуализация с plotly
Для интерактивных дашбордов или веб-приложений стоит использовать plotly, который позволяет создавать динамические визуализации:
import plotly.express as px
import plotly.graph_objects as go
# Создаем базовую интерактивную гистограмму
fig = px.bar(x=fruits.value_counts().index,
y=fruits.value_counts().values,
labels={'x': 'Фрукты', 'y': 'Количество'},
title='Интерактивная визуализация результатов value_counts()')
# Добавляем интерактивные элементы
fig.update_traces(hovertemplate='Фрукт: %{x}<br>Количество: %{y}')
fig.update_layout(hovermode='closest')
# Для HTML/Jupyter
fig.show()
# Создаем интерактивную тепловую карту для многомерных данных
# Сначала создадим сводную таблицу
pivot = pd.crosstab(df['fruit'], df['quality'])
# Создаем тепловую карту
fig = px.imshow(pivot,
labels=dict(x="Качество", y="Фрукт", color="Количество"),
title="Тепловая карта распределения фруктов по качеству")
# Добавляем текстовые аннотации с точными значениями
fig.update_traces(text=pivot.values, texttemplate="%{text}")
fig.show()
Оптимизация визуализации для особых случаев
В некоторых сценариях стандартная визуализация может быть неоптимальной. Вот несколько приемов для работы с особыми случаями:
- Объединение редких категорий: Если у вас много редких категорий, их можно объединить в одну для улучшения читаемости графика
- Логарифмические шкалы: Для данных с большой разницей между значениями лучше использовать логарифмическую шкалу
- Горизонтальные графики: Для данных с длинными названиями категорий лучше использовать горизонтальные гистограммы
- Faceting: Разбиение данных на подграфики для лучшего сравнения разных групп
# Объединение редких категорий
def plot_with_others(series, threshold=0.05):
"""Визуализирует результаты value_counts(), объединяя редкие категории в 'Другое'"""
counts = series.value_counts(normalize=True)
mask = counts >= threshold
# Создаем новую серию с объединенными редкими категориями
plot_data = pd.Series(
list(counts[mask]) + [counts[~mask].sum()],
index=list(counts[mask].index) + ['Другое']
)
# Визуализируем
plot_data.plot(kind='pie', autopct='%1.1f%%', figsize=(10, 6))
plt.title(f'Распределение с порогом {threshold*100}%')
plt.show()
# Применение функции
plot_with_others(fruits, threshold=0.2)
Визуализация результатов value_counts()
— это не просто способ сделать отчет более привлекательным. Это инструмент, который существенно ускоряет процесс анализа, помогает выявлять закономерности и делает результаты более понятными для нетехнических специалистов. 📊
Тест на профориентацию от Skypro поможет определить, подходит ли вам карьера в анализе данных. Не уверены, стоит ли изучать Pandas и другие инструменты аналитики? За 5 минут узнайте, совпадают ли ваши природные склонности с требованиями профессии дата-аналитика. Тест разработан психологами и HR-экспертами ведущих технологических компаний, чтобы помочь вам сделать осознанный выбор карьерного пути.
Оптимизация анализа данных с применением Value Counts
Эффективный анализ данных требует не только правильного применения инструментов, но и оптимизации процессов. Value_counts()
может стать мощным оружием в руках аналитика, если использовать его стратегически для ускорения работы с данными и повышения качества анализа. Рассмотрим несколько подходов к оптимизации анализа с помощью этой функции. 🚀
Оптимизация производительности
При работе с крупными датасетами производительность value_counts()
может стать критически важной. Вот несколько советов по оптимизации:
# Использование категориальных данных для оптимизации памяти
# Преобразование столбца в категориальный тип перед применением value_counts()
import pandas as pd
import numpy as np
# Создаем большой датасет (1 миллион строк)
data = pd.DataFrame({
'category': np.random.choice(['A', 'B', 'C', 'D', 'E'], size=1000000),
'numeric': np.random.normal(0, 1, size=1000000)
})
# Замеряем время выполнения на стандартных строковых данных
%time regular_counts = data['category'].value_counts()
# Преобразуем в категориальный тип
data['category'] = data['category'].astype('category')
# Замеряем время на категориальных данных
%time optimized_counts = data['category'].value_counts()
# Разница может быть существенной на больших датасетах
# Особенно при многократном вызове value_counts()
Дополнительные приемы оптимизации:
- Применение
value_counts()
к подмножеству данных с помощью фильтрации, если вы анализируете только часть датасета - Использование параметра
dropna=True
(по умолчанию) для исключения NaN значений, если они не нужны для анализа - Кэширование результатов
value_counts()
при повторном использовании - Применение метода
value_counts()
к цепочкам фильтраций для более эффективной работы памяти
Автоматизация аналитических процессов
Value_counts()
можно эффективно использовать в автоматизированных аналитических процессах:
# Создаем функцию для автоматического анализа категориальных переменных
def categorical_analysis(df, threshold=0.01):
"""
Автоматически анализирует все категориальные столбцы в датафрейме:
- Подсчитывает частоты
- Отображает редкие категории (меньше threshold)
- Вычисляет энтропию (меру неопределенности)
"""
results = {}
# Получаем список категориальных столбцов
categorical_cols = df.select_dtypes(include=['object', 'category']).columns
for col in categorical_cols:
# Подсчитываем частоты
counts = df[col].value_counts(normalize=True)
# Находим редкие категории
rare_values = counts[counts < threshold].index.tolist()
# Вычисляем энтропию (-sum(p*log(p)))
entropy = -np.sum(counts * np.log(counts))
results[col] = {
'total_categories': len(counts),
'top_category': counts.index[0],
'top_category_percentage': f"{counts.values[0]*100:.2f}%",
'rare_categories': rare_values,
'rare_categories_count': len(rare_values),
'entropy': entropy,
'distribution': counts
}
return results
# Применяем функцию к датафрейму
analysis_results = categorical_analysis(df, threshold=0.05)
# Выводим результаты в виде структурированного отчета
for column, stats in analysis_results.items():
print(f"\n=== Анализ столбца: {column} ===")
print(f"Всего категорий: {stats['total_categories']}")
print(f"Самая частая категория: {stats['top_category']} ({stats['top_category_percentage']})")
print(f"Количество редких категорий: {stats['rare_categories_count']}")
print(f"Энтропия распределения: {stats['entropy']:.4f}")
# Визуализируем топ-5 категорий
stats['distribution'].head(5).plot(kind='bar')
plt.title(f'Топ-5 категорий в {column}')
plt.tight_layout()
plt.show()
Интеграция в процессы Feature Engineering
Value_counts()
может быть эффективно использован для создания новых признаков на основе распределения данных:
# Создание бинарных признаков для редких категорий
def encode_rare_categories(df, column, threshold=0.05):
"""
Заменяет редкие категории на 'OTHER' и создает бинарный признак
"""
# Находим редкие категории
counts = df[column].value_counts(normalize=True)
rare_mask = counts < threshold
rare_categories = counts[rare_mask].index.tolist()
# Создаем новый столбец с замененными редкими категориями
df[f"{column}_processed"] = df[column].apply(
lambda x: 'OTHER' if x in rare_categories else x
)
# Создаем бинарный признак
df[f"{column}_is_rare"] = df[column].apply(
lambda x: 1 if x in rare_categories else 0
)
return df
# Пример использования
df = encode_rare_categories(df, 'product_category', threshold=0.1)
# Для числовых переменных можно создать бины на основе распределения
def create_quantile_bins(df, column, n_bins=5):
"""
Создает новый категориальный признак на основе квантилей числовой переменной
"""
df[f"{column}_bin"] = pd.qcut(df[column], q=n_bins, labels=False)
# Анализируем распределение по бинам
bin_counts = df[f"{column}_bin"].value_counts().sort_index()
print(f"Распределение по бинам для {column}:")
print(bin_counts)
return df
# Пример использования
df = create_quantile_bins(df, 'price', n_bins=4)
Интеграция с машинным обучением
Value_counts()
играет важную роль в подготовке данных для моделей машинного обучения:
- Выявление несбалансированности классов в задачах классификации
- Определение стратегии семплирования (под-выборки или над-выборки)
- Автоматическое создание категориальных признаков
- Валидация результатов модели путем сравнения предсказанных и фактических распределений
# Пример анализа несбалансированности классов
from sklearn.model_selection import train_test_split
from sklearn.ensemble import RandomForestClassifier
from sklearn.metrics import classification_report
# Подготовка данных
X = df[['feature1', 'feature2', 'feature3']]
y = df['target'] # Целевая переменная
# Анализируем распределение целевой переменной
class_distribution = y.value_counts(normalize=True)
print("Распределение классов:")
print(class_distribution)
# Определяем, нужна ли коррекция несбалансированности
is_imbalanced = any(class_distribution < 0.2) # Произвольный порог
if is_imbalanced:
# Устанавливаем веса классов обратно пропорционально их частоте
class_weights = {i: 1.0/count for i, count in enumerate(class_distribution)}
print("Применяем веса классов:", class_weights)
else:
class_weights = None
# Разделяем данные на обучающую и тестовую выборки
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state=42)
# Обучаем модель с учетом весов классов
model = RandomForestClassifier(class_weight=class_weights)
model.fit(X_train, y_train)
# Оцениваем результаты
y_pred = model.predict(X_test)
# Сравниваем распределения предсказанных и фактических классов
print("Распределение фактических классов в тестовой выборке:")
print(y_test.value_counts(normalize=True))
print("Распределение предсказанных классов:")
print(pd.Series(y_pred).value_counts(normalize=True))
# Подробный отчет по метрикам
print(classification_report(y_test, y_pred))
Интеграция value_counts()
в различные этапы анализа данных и машинного обучения значительно повышает эффективность работы аналитика. Этот метод, несмотря на свою простоту, становится незаменимым инструментом для быстрой оценки данных, выявления закономерностей и подготовки данных к моделированию. ⚡
Подводя итог,
value_counts()
— это гораздо больше, чем просто функция для подсчета значений. Это мощный аналитический инструмент, способный существенно ускорить процесс исследования данных, выявить скрытые закономерности и повысить качество принимаемых решений. От базового применения до интеграции с машинным обучением — овладение этой функцией и её параметрами даёт аналитику возможность быстро получать значимые инсайты из данных. Превратитеvalue_counts()
из обычной функции подсчёта в стратегический инструмент вашего аналитического арсенала — и вы увидите, как структурированный подход к анализу данных открывает новые горизонты для вашей работы.