Работа с Pandas в Python: аналог SQL запроса 'count(distinct)'

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

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

Быстрый ответ

Чтобы подсчитать количество уникальных значений в Pandas, аналогично функции COUNT(DISTINCT) в SQL, можно воспользоваться комбинацией методов .groupby() и .nunique().

Python
Скопировать код
unique_counts = df.groupby('key')['value'].nunique()

Данный отрывок кода создаст объект Series, который будет подсчитывать количество уникальных значений в колонке 'value' для каждого ключа 'key'.

Если есть необходимость преобразовать результат в DataFrame и добавить дополнительные агрегирующие функции, используйте метод .agg():

Python
Скопировать код
unique_counts_df = df.groupby('key').agg({'value': 'nunique'})  # Получаем более информативный DataFrame!
Кинга Идем в IT: пошаговый план для смены профессии

Различные подходы к подсчёту: Groupby и агрегирование

Использование 'nunique' для учёта уникальных значений

Если нужно подсчитать уникальные значения по нескольким столбцам, стоит использовать метод agg():

Python
Скопировать код
# Чем больше колонок, тем интереснее!
result = df.groupby('YEARMONTH').agg({
    'CLIENTCODE': 'nunique',        # уникальные коды клиентов
    'TRANSACTIONTYPE': 'nunique',   # различные типы транзакций
    'TOTALSALES': 'sum'             # общий объем продаж
})

Сохраняем индекс

Метод groupby() по умолчанию преобразует ключи в индексы в новом DataFrame:

Python
Скопировать код
result.reset_index(inplace=True)  # "Возврати мой индекс, пожалуйста!"

Сброс индекса помогает сохранить исходную структуру DataFrame и облегчает его дальнейшую обработку.

Преобразование после агрегации

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

Python
Скопировать код
# Для лаконичности и порядка!
result.columns = ['_'.join(col).strip() for col in result.columns.values]

Такое изменение делает названия столбцов более понятными для последующих манипуляций.

Изучаем глубже: метод transform в Pandas

Сохранение структуры оригинального DataFrame с помощью 'transform'

Если вам нужно добавить в исходный DataFrame столбец с количеством уникальных значений, используйте метод transform:

Python
Скопировать код
# Трансформация: добавляем полезные данные, не меняя внешний вид!
df['unique_count'] = df.groupby('key')['value'].transform('nunique')

Метод transform применяет функцию к каждой группе, при этом сохраняя структуру и размер исходного DataFrame.

Использование разных агрегатов с transform

Функция transform в Pandas позволяет использовать различные агрегирующие функции:

Python
Скопировать код
# Устанавливаем рекорды продаж в каждом регионе!
df['max_sales'] = df.groupby('region')['sales'].transform('max')

В результате мы получим новый столбец, где для каждого региона будут указаны максимальные продажи.

Альтернативы и особые случаи

Подсчёт уникальных значений без использования groupby

Чтобы подсчитать уникальные значения во всём столбце:

Python
Скопировать код
# Клиенты, каждый из вас уникален!
unique_client_count = df['CLIENTCODE'].nunique()

Здесь возвращается общее число уникальных клиентов в данных.

Не только удобный инструмент: 'value_counts()'

Метод value_counts() идеально подходит для быстрой оценки частоты встречаемости уникальных значений:

Python
Скопировать код
# 'CLIENTCODE', покажи нам свою популярность!
frequencies = df['CLIENTCODE'].value_counts()

Важно учесть, что value_counts() подсчитывает частоту появления значений, а не уникальные категории.

Визуализация

Представьте себе сад, где растут разные виды фруктов:

Markdown
Скопировать код
🌳 Яблоня (🍏): [Зелёное, Красное, Зелёное, Жёлтое, Красное]
🌳 Апельсиновое дерево (🍊): [Большой, Маленький, Большой, Большой]
🌳 Грушевое дерево (🍐): [Спелая, Неспелая, Спелая]

Мы хотим узнать число уникальных видов каждого фрукта, аналогично count(distinct) в Pandas:

Применяя nunique(), словно умная корзина:

Python
Скопировать код
basket = 🧺
basket.add_all_from_tree(🌳)
basket.count_unique() # 🧠🧺

И мы получим:

Markdown
Скопировать код
🍏: 3 уникальных цвета | 🧺 Результат: [Зелёное, Красное, Жёлтое]
🍊: 2 уникальных размера | 🧺 Результат: [Большой, Маленький]
🍐: 2 уникальных состояния спелости | 🧺 Результат: [Спелая, Неспелая]

С помощью nunique() в Pandas каждый вид фруктов подсчитывается отдельно, что подтверждает удобство именно этого метода.

Управление сложностью: дальше основ

Когда SQL недоступен

В тех случаях, когда нет возможности использовать базу данных для SQL-запросов, Pandas предлагает мощные инструменты для сложной обработки данных. Эмуляция операции COUNT(DISTINCT) это лишь одна из множества функциональностей представленных в Pandas.

Работа с большим объёмом данных

Задача подсчёта уникальных значений в больших данных может быть трудоёмкой и замедлять обработку. В таких случаях можно опробовать разделить данные на части или использовать метод .drop_duplicates() перед агрегацией для увеличения производительности.

Null и отсутствующие значения

В Pandas значения null рассматриваются как неуникальные, в соответствии с SQL COUNT(DISTINCT). Чтобы расценивать null как уникальные значения, их нужно заменить на некоторый уникальный идентификатор.

Полезные материалы

  1. pandas.Series.value_counts — документация pandas 2.2.0 — Документация Pandas, описывающая использование метода value_counts.
  2. pandas.DataFrame.drop_duplicates — документация pandas 2.2.0 — Руководство по удалению дубликатов в DataFrame для оптимизации подсчёта уникальных значений.
  3. pandas.DataFrame.groupby — документация pandas 2.2.0 — Пояснение принципов группировки данных.
  4. python – Эквивалент 'count(distinct)' в Pandas – Stack Overflow — Обсуждение на Stack Overflow на тему эмуляции COUNT(DISTINCT) в Pandas.
  5. pandas.Series.nunique — документация pandas 2.2.0 — Документация к методу nunique, служащему для подсчёта уникальных значений.
  6. pandas.DataFrame.agg — документация pandas 2.2.0 — Инструкция по применению функции агрегирования agg в Pandas.