Pandas Value Counts: быстрый анализ и подсчет уникальных значений

Пройдите тест, узнайте какой профессии подходите

Я предпочитаю
0%
Работать самостоятельно и не зависеть от других
Работать в команде и рассчитывать на помощь коллег
Организовывать и контролировать процесс работы

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

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

    Когда имеешь дело с гигабайтами данных, ключевой задачей становится быстро понять, из чего состоит твой датасет. Именно здесь на сцену выходит метод 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() сэкономил компании время и деньги.

Кинга Идем в IT: пошаговый план для смены профессии

Синтаксис и базовые параметры функции value_counts()

Функция value_counts() имеет простой, но гибкий синтаксис, который позволяет настроить подсчет уникальных значений под ваши конкретные потребности. Базовый вызов выглядит следующим образом:

Python
Скопировать код
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Возвращает относительные частоты вместо абсолютныхFalses.value_counts(normalize=True)
sortСортировка результатов по частотеTrues.value_counts(sort=False)
ascendingСортировка по возрастанию вместо убыванияFalses.value_counts(ascending=True)
dropnaИсключение NaN значений из подсчетаTrues.value_counts(dropna=False)
binsГруппировка числовых данных по интерваламNonepd.Series([1, 2, 3, 4]).value_counts(bins=2)

Рассмотрим практические примеры использования этих параметров:

Python
Скопировать код
# Получение относительных частот (доли вместо абсолютных значений)
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:

Python
Скопировать код
# Создаем 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

Условный подсчет и фильтрация

Иногда нужно подсчитать значения, соответствующие определенным критериям или выполнить фильтрацию после подсчета:

Python
Скопировать код
# Подсчет с фильтрацией результатов
# Показать только страны с более чем 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()

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

Python
Скопировать код
# Добавим категорию продукта
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():

Python
Скопировать код
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:

Python
Скопировать код
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, который позволяет создавать динамические визуализации:

Python
Скопировать код
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: Разбиение данных на подграфики для лучшего сравнения разных групп
Python
Скопировать код
# Объединение редких категорий
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() может стать критически важной. Вот несколько советов по оптимизации:

Python
Скопировать код
# Использование категориальных данных для оптимизации памяти
# Преобразование столбца в категориальный тип перед применением 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() можно эффективно использовать в автоматизированных аналитических процессах:

Python
Скопировать код
# Создаем функцию для автоматического анализа категориальных переменных
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() может быть эффективно использован для создания новых признаков на основе распределения данных:

Python
Скопировать код
# Создание бинарных признаков для редких категорий
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() играет важную роль в подготовке данных для моделей машинного обучения:

  • Выявление несбалансированности классов в задачах классификации
  • Определение стратегии семплирования (под-выборки или над-выборки)
  • Автоматическое создание категориальных признаков
  • Валидация результатов модели путем сравнения предсказанных и фактических распределений
Python
Скопировать код
# Пример анализа несбалансированности классов
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() из обычной функции подсчёта в стратегический инструмент вашего аналитического арсенала — и вы увидите, как структурированный подход к анализу данных открывает новые горизонты для вашей работы.