Работа с Pandas в Python: аналог SQL запроса 'count(distinct)'
Быстрый ответ
Чтобы подсчитать количество уникальных значений в Pandas, аналогично функции COUNT(DISTINCT)
в SQL, можно воспользоваться комбинацией методов .groupby()
и .nunique()
.
unique_counts = df.groupby('key')['value'].nunique()
Данный отрывок кода создаст объект Series, который будет подсчитывать количество уникальных значений в колонке 'value' для каждого ключа 'key'.
Если есть необходимость преобразовать результат в DataFrame и добавить дополнительные агрегирующие функции, используйте метод .agg()
:
unique_counts_df = df.groupby('key').agg({'value': 'nunique'}) # Получаем более информативный DataFrame!
Различные подходы к подсчёту: Groupby и агрегирование
Использование 'nunique' для учёта уникальных значений
Если нужно подсчитать уникальные значения по нескольким столбцам, стоит использовать метод agg():
# Чем больше колонок, тем интереснее!
result = df.groupby('YEARMONTH').agg({
'CLIENTCODE': 'nunique', # уникальные коды клиентов
'TRANSACTIONTYPE': 'nunique', # различные типы транзакций
'TOTALSALES': 'sum' # общий объем продаж
})
Сохраняем индекс
Метод groupby()
по умолчанию преобразует ключи в индексы в новом DataFrame:
result.reset_index(inplace=True) # "Возврати мой индекс, пожалуйста!"
Сброс индекса помогает сохранить исходную структуру DataFrame и облегчает его дальнейшую обработку.
Преобразование после агрегации
Для более комфортной работы с DataFrame после агрегации, особенно в случае многоуровневого индекса, полезно упорядочить структуру данных:
# Для лаконичности и порядка!
result.columns = ['_'.join(col).strip() for col in result.columns.values]
Такое изменение делает названия столбцов более понятными для последующих манипуляций.
Изучаем глубже: метод transform в Pandas
Сохранение структуры оригинального DataFrame с помощью 'transform'
Если вам нужно добавить в исходный DataFrame столбец с количеством уникальных значений, используйте метод transform
:
# Трансформация: добавляем полезные данные, не меняя внешний вид!
df['unique_count'] = df.groupby('key')['value'].transform('nunique')
Метод transform применяет функцию к каждой группе, при этом сохраняя структуру и размер исходного DataFrame.
Использование разных агрегатов с transform
Функция transform
в Pandas позволяет использовать различные агрегирующие функции:
# Устанавливаем рекорды продаж в каждом регионе!
df['max_sales'] = df.groupby('region')['sales'].transform('max')
В результате мы получим новый столбец, где для каждого региона будут указаны максимальные продажи.
Альтернативы и особые случаи
Подсчёт уникальных значений без использования groupby
Чтобы подсчитать уникальные значения во всём столбце:
# Клиенты, каждый из вас уникален!
unique_client_count = df['CLIENTCODE'].nunique()
Здесь возвращается общее число уникальных клиентов в данных.
Не только удобный инструмент: 'value_counts()'
Метод value_counts()
идеально подходит для быстрой оценки частоты встречаемости уникальных значений:
# 'CLIENTCODE', покажи нам свою популярность!
frequencies = df['CLIENTCODE'].value_counts()
Важно учесть, что value_counts()
подсчитывает частоту появления значений, а не уникальные категории.
Визуализация
Представьте себе сад, где растут разные виды фруктов:
🌳 Яблоня (🍏): [Зелёное, Красное, Зелёное, Жёлтое, Красное]
🌳 Апельсиновое дерево (🍊): [Большой, Маленький, Большой, Большой]
🌳 Грушевое дерево (🍐): [Спелая, Неспелая, Спелая]
Мы хотим узнать число уникальных видов каждого фрукта, аналогично count(distinct)
в Pandas:
Применяя nunique()
, словно умная корзина:
basket = 🧺
basket.add_all_from_tree(🌳)
basket.count_unique() # 🧠🧺
И мы получим:
🍏: 3 уникальных цвета | 🧺 Результат: [Зелёное, Красное, Жёлтое]
🍊: 2 уникальных размера | 🧺 Результат: [Большой, Маленький]
🍐: 2 уникальных состояния спелости | 🧺 Результат: [Спелая, Неспелая]
С помощью nunique()
в Pandas каждый вид фруктов подсчитывается отдельно, что подтверждает удобство именно этого метода.
Управление сложностью: дальше основ
Когда SQL недоступен
В тех случаях, когда нет возможности использовать базу данных для SQL-запросов, Pandas предлагает мощные инструменты для сложной обработки данных. Эмуляция операции COUNT(DISTINCT)
это лишь одна из множества функциональностей представленных в Pandas.
Работа с большим объёмом данных
Задача подсчёта уникальных значений в больших данных может быть трудоёмкой и замедлять обработку. В таких случаях можно опробовать разделить данные на части или использовать метод .drop_duplicates()
перед агрегацией для увеличения производительности.
Null и отсутствующие значения
В Pandas значения null рассматриваются как неуникальные, в соответствии с SQL COUNT(DISTINCT)
. Чтобы расценивать null как уникальные значения, их нужно заменить на некоторый уникальный идентификатор.
Полезные материалы
- pandas.Series.value_counts — документация pandas 2.2.0 — Документация Pandas, описывающая использование метода
value_counts
. - pandas.DataFrame.drop_duplicates — документация pandas 2.2.0 — Руководство по удалению дубликатов в DataFrame для оптимизации подсчёта уникальных значений.
- pandas.DataFrame.groupby — документация pandas 2.2.0 — Пояснение принципов группировки данных.
- python – Эквивалент 'count(distinct)' в Pandas – Stack Overflow — Обсуждение на Stack Overflow на тему эмуляции
COUNT(DISTINCT)
в Pandas. - pandas.Series.nunique — документация pandas 2.2.0 — Документация к методу
nunique
, служащему для подсчёта уникальных значений. - pandas.DataFrame.agg — документация pandas 2.2.0 — Инструкция по применению функции агрегирования
agg
в Pandas.