5 способов подсчета уникальных значений в pandas: полное руководство
Пройдите тест, узнайте какой профессии подходите
Для кого эта статья:
- специалисты по аналитике данных и программисты-практики
- студенты и начинающие аналитики, желающие улучшить навыки работы с pandas
- профессионалы, работающие с большими объемами данных и заинтересованные в оптимизации процессов анализа
Работа с дубликатами в данных — ключевой навык каждого аналитика, меняющий результаты исследований кардинально. Подсчет уникальных значений в pandas, казалось бы, тривиальная задача, но она скрывает множество нюансов, влияющих на скорость обработки больших датасетов и точность ваших выводов. Разница между неоптимальным и эффективным методом может составлять минуты, а иногда и часы вычислительного времени! 📊 Разберем пять проверенных техник, позволяющих превратить эту рутинную операцию в мощный инструмент анализа.
Погружение в тонкости вычисления уникальных значений — лишь первый шаг в становлении профессионального аналитика данных. Хотите овладеть полным арсеналом инструментов для работы с данными? Курс «Python-разработчик» с нуля от Skypro предлагает глубокое погружение в pandas, numpy и другие библиотеки, с практическими кейсами от действующих экспертов. Научитесь не только чистить данные, но и создавать законченные аналитические решения, востребованные на рынке.
Почему подсчет уникальных значений важен при анализе данных
Подсчет уникальных значений — фундаментальная операция в аналитике данных, которая влияет на все последующие шаги анализа. Когда мы работаем с реальными датасетами, особенно большого объема, понимание кардинальности (количества уникальных значений) каждого признака критически важно по нескольким причинам:
- Выявление структуры данных — помогает понять дискретность признака и его потенциальное влияние как предиктора
- Выбор подходящих методов обработки — категориальные признаки с малым числом уникальных значений требуют иного подхода, чем непрерывные переменные
- Обнаружение аномалий — неожиданно высокое или низкое количество уникальных значений может сигнализировать о проблемах качества данных
- Оптимизация памяти — знание кардинальности позволяет выбрать экономичные типы данных для хранения
- Подготовка к машинному обучению — влияет на выбор алгоритмов кодирования категориальных данных
Александр Викторов, Lead Data Scientist
Однажды мой проект едва не провалился из-за игнорирования простой проверки уникальности. Мы строили рекомендательную систему для крупного маркетплейса, и модель показывала впечатляющие метрики на тестовой выборке. Но в продакшене что-то пошло не так — пользователи жаловались на странные рекомендации.
Оказалось, что в колонке customer_id присутствовали дубликаты, созданные после миграции с другой CRM-системы. При проверке уникальных значений мы обнаружили, что вместо ожидаемых 1.2 млн уникальных пользователей у нас было всего 900 тысяч. Для некоторых клиентов история покупок смешивалась, что полностью искажало персонализацию. Простой вызов df['customer_id'].nunique() мог предотвратить недели работы команды над поиском причин проблемы.
На практике существует несколько сценариев, где подсчет уникальных значений становится критичным:
Сценарий | Почему важен подсчет уникальных значений | Последствия игнорирования |
---|---|---|
Предварительная обработка данных | Определяет стратегию кодирования категориальных признаков | Неэффективное использование памяти, медленные вычисления |
Разведочный анализ | Помогает выявить структуру и распределения в данных | Неполное понимание особенностей датасета |
Оценка качества данных | Выявляет потенциальные дубликаты и аномалии | Некорректные аналитические выводы |
Агрегация данных | Принципиально важна для правильных GROUP BY операций | Искажение результатов агрегации |
Оценка признаков для ML | Влияет на выбор алгоритмов и проектирование признаков | Снижение предсказательной силы моделей |
Теперь, понимая важность правильного подсчета уникальных значений, давайте рассмотрим пять мощных методов, которые предлагает pandas для этой задачи в 2025 году. 🔍

Метод pandas.Series.nunique() для быстрого count unique values
Самый элегантный и лаконичный способ подсчета уникальных значений в pandas — метод nunique(). Это встроенная функция для объектов Series, позволяющая с минимальными усилиями получить количество уникальных непустых (non-NA/null) значений:
import pandas as pd
# Создаем простой пример Series
s = pd.Series([1, 2, 2, 3, 3, 3, 4, None, None])
# Подсчитываем уникальные значения
unique_count = s.nunique()
print(f"Количество уникальных значений: {unique_count}") # Выведет: 4
# С учетом NaN значений
unique_count_with_nan = s.nunique(dropna=False)
print(f"Количество уникальных значений (включая NaN): {unique_count_with_nan}") # Выведет: 5
Метод nunique() обладает несколькими важными преимуществами, делающими его предпочтительным выбором в большинстве сценариев:
- Лаконичность — требует минимум кода для достижения результата
- Высокая производительность — оптимизирован на уровне C для быстрой работы
- Гибкость с пропущенными значениями — параметр dropna позволяет контролировать учет NaN
- Прямая поддержка для DataFrame — можно применить к целым датафреймам
Когда работаете с DataFrame, nunique() можно использовать двумя способами — для отдельного столбца или для всей таблицы:
# Подсчет уникальных значений в конкретном столбце
df = pd.DataFrame({
'A': [1, 1, 2, 3],
'B': ['a', 'a', 'b', 'c'],
'C': [None, 1, 2, None]
})
# Для отдельного столбца
print(df['A'].nunique()) # Выведет: 3
# Для всего DataFrame (вернет Series с результатами по каждому столбцу)
print(df.nunique())
# Выведет:
# A 3
# B 3
# C 2
# dtype: int64
Параметр axis позволяет подсчитывать уникальность по строкам (axis=0) или по столбцам (axis=1), что особенно полезно при анализе структуры данных:
# Подсчет уникальных значений по строкам
print(df.nunique(axis=1))
# Выведет количество уникальных значений для каждой строки
В 2025 году метод nunique() получил дополнительную оптимизацию производительности, особенно для датасетов с миллионами строк, что делает его еще более привлекательным для аналитиков данных, работающих с крупными массивами информации. 🚀
Использование pandas.DataFrame.drop_duplicates() с подсчетом
Более гибкий подход к вычислению уникальных значений предлагает метод drop_duplicates(). В отличие от nunique(), который просто возвращает число, этот метод сначала удаляет дубликаты, а затем позволяет подсчитать оставшиеся записи, предоставляя больше контроля над процессом:
import pandas as pd
df = pd.DataFrame({
'A': [1, 1, 2, 2, 3],
'B': ['a', 'a', 'b', 'b', 'c'],
'C': [1, 1, 1, 2, 2]
})
# Подсчет уникальных комбинаций значений в столбцах A и B
unique_ab_count = df.drop_duplicates(subset=['A', 'B']).shape[0]
print(f"Уникальных комбинаций A+B: {unique_ab_count}") # Выведет: 3
# Подсчет уникальных значений только по столбцу B
unique_b_count = df.drop_duplicates(subset=['B']).shape[0]
print(f"Уникальных значений B: {unique_b_count}") # Выведет: 3
# Подсчет полностью уникальных строк
unique_rows = df.drop_duplicates().shape[0]
print(f"Полностью уникальных строк: {unique_rows}") # Выведет: 4
Ключевые параметры метода drop_duplicates(), о которых следует знать:
- subset: список столбцов для проверки дубликатов (по умолчанию все столбцы)
- keep: 'first' (оставить первый дубликат), 'last' (оставить последний) или False (удалить все дубликаты)
- ignore_index: если True, результирующий DataFrame будет иметь новые индексы от 0 до n-1
Мария Соколова, Data Analyst
В моей практике был случай, когда простой подсчет уникальных значений с помощью nunique() создал ошибочное представление о данных. Мы анализировали логи пользовательского поведения на крупном e-commerce сайте, где каждая запись содержала множество атрибутов о пользователе и его действиях.
При подготовке еженедельного отчета о конверсии мы заметили аномально высокие показатели. Мой коллега использовал df['user_id'].nunique() для подсчета уникальных пользователей, но это не учитывало бизнес-логику: нас интересовали только пользователи, завершившие определенную последовательность действий.
Я переписала код с использованием drop_duplicates():
PythonСкопировать кодcompleted_users = df[df['action_completed'] == True].drop_duplicates(subset=['user_id', 'session_id']).shape[0]
Результаты мгновенно изменились, показав реальную картину конверсии, которая была на 23% ниже изначальных расчетов. Этот подход позволил нам точно определить, сколько уникальных пользователей действительно прошли весь путь покупки, а не просто посетили сайт.
Одно из мощных применений drop_duplicates() — анализ уникальности по нескольким измерениям одновременно, что невозможно сделать напрямую через nunique():
Сценарий | Код с drop_duplicates() | Преимущество перед nunique() |
---|---|---|
Кросс-секционный анализ | df.drop_duplicates(['region', 'product']).shape[0] | Позволяет оценить уникальность по комбинации критериев |
Временные ряды с группировкой | df.drop_duplicates(['customer_id', 'date']).shape[0] | Учитывает временное измерение при подсчете |
Анализ с фильтрацией | df[df['status']=='active'].drop_duplicates(['id']).shape[0] | Комбинирует фильтрацию и удаление дубликатов |
Сравнение разных периодов | df[df['year']==2024].drop_duplicates(['customer']).shape[0] | Позволяет легко сравнивать метрики между периодами |
Подход с drop_duplicates() особенно ценен, когда требуется не просто количество уникальных значений, но и сами эти значения для дальнейшего анализа или обработки. 🧮
Комбинация pandas.value_counts() для подсчета уникальных значений
Функция value_counts() представляет третий мощный метод для анализа уникальных значений, особенно когда нам важно не только их количество, но и частотное распределение. Этот метод возвращает Series с подсчетом вхождений каждого уникального элемента, что дает гораздо более богатую информацию для анализа:
import pandas as pd
import numpy as np
# Создаем пример данных
df = pd.DataFrame({
'категория': ['A', 'B', 'A', 'C', 'B', 'B', 'A', None, 'D', 'D'],
'ценник': [100, 200, 100, 300, 200, 250, 100, 400, None, 500]
})
# Получаем распределение частот для категорий
category_counts = df['категория'].value_counts()
print("Распределение категорий:")
print(category_counts)
# Выведет:
# B 3
# A 3
# D 2
# C 1
# Name: категория, dtype: int64
# Количество уникальных категорий
unique_categories = len(category_counts)
print(f"Количество уникальных категорий: {unique_categories}") # Выведет: 4
# С учетом NA значений
category_counts_with_na = df['категория'].value_counts(dropna=False)
print("\nС учетом NA:")
print(category_counts_with_na)
Метод value_counts() предлагает множество полезных параметров, значительно расширяющих возможности анализа:
- normalize: если True, возвращает относительные частоты (доли) вместо абсолютных
- sort: сортировка по частоте (по умолчанию True)
- ascending: порядок сортировки (по умолчанию False, т.е. от большей частоты к меньшей)
- dropna: учитывать ли пропущенные значения (по умолчанию True)
- bins: группировка числовых данных по интервалам (бинам)
Использование value_counts() для получения относительной частоты (пропорции) уникальных значений:
# Относительная частота
relative_freq = df['категория'].value_counts(normalize=True)
print("Относительная частота:")
print(relative_freq)
# Выведет:
# B 0.333333
# A 0.333333
# D 0.222222
# C 0.111111
# Name: категория, dtype: float64
Для числовых данных value_counts() можно комбинировать с bins для анализа распределения по интервалам:
# Группировка числовых данных по интервалам
price_distribution = df['ценник'].value_counts(bins=3)
print("\nРаспределение цен по интервалам:")
print(price_distribution)
Мощь метода value_counts() раскрывается при комбинировании его с другими операциями pandas:
# Подсчет уникальных значений после фильтрации
expensive_categories = df[df['ценник'] > 200]['категория'].value_counts()
print("\nРаспределение категорий для товаров дороже 200:")
print(expensive_categories)
# Комбинирование с groupby для многомерного анализа
prices_by_category = df.groupby('категория')['ценник'].value_counts()
print("\nРаспределение цен внутри категорий:")
print(prices_by_category)
Для более глубокого анализа часто полезно визуализировать результаты value_counts():
import matplotlib.pyplot as plt
# Визуализация распределения категорий
df['категория'].value_counts().plot(kind='bar')
plt.title('Распределение категорий')
plt.ylabel('Количество')
plt.xlabel('Категория')
# plt.show() # Раскомментируйте для отображения графика
Метод value_counts() особенно полезен на этапе разведочного анализа данных, когда важно понять не только количество уникальных значений, но и структуру их распределения. Это часто помогает выявить закономерности и аномалии в данных, которые могут быть не очевидны при простом подсчете уникальности. 📊
Понимание различных методов подсчета уникальных значений — лишь одна из множества компетенций, необходимых современному специалисту по данным. Если вы задумываетесь о карьере в этой области, но не уверены в своем призвании, Тест на профориентацию от Skypro поможет определить, подходит ли вам аналитика данных или программирование. Объективная оценка ваших сильных сторон и предпочтений позволит избежать карьерных ошибок и найти путь, где практические навыки работы с pandas принесут максимальную отдачу.
Оптимизация производительности при подсчете уникальных значений
При работе с большими объемами данных (от 100+ млн строк) вопрос производительности при подсчете уникальных значений становится критичным. Стандартные методы pandas могут работать неожиданно медленно, особенно при ограниченных ресурсах. Рассмотрим передовые техники оптимизации, актуальные в 2025 году:
import pandas as pd
import numpy as np
import time
# Создаем крупный датафрейм для тестирования (10 млн строк)
n = 10_000_000
df_large = pd.DataFrame({
'id': np.random.randint(0, 1_000_000, n),
'category': np.random.choice(['A', 'B', 'C', 'D', 'E'], n),
'value': np.random.random(n)
})
# 1. Стандартный подход с nunique()
start = time.time()
nunique_count = df_large['id'].nunique()
nunique_time = time.time() – start
print(f"nunique() нашел {nunique_count} уникальных значений за {nunique_time:.4f} секунд")
# 2. Оптимизация через set (часто быстрее для больших датасетов)
start = time.time()
set_count = len(set(df_large['id']))
set_time = time.time() – start
print(f"set() нашел {set_count} уникальных значений за {set_time:.4f} секунд")
# 3. Использование numpy.unique (может быть быстрее для числовых данных)
start = time.time()
np_count = len(np.unique(df_large['id']))
np_time = time.time() – start
print(f"np.unique() нашел {np_count} уникальных значений за {np_time:.4f} секунд")
На практике выбор оптимального метода зависит от типа данных и размера датасета. Вот сравнительная таблица производительности различных методов для типичных сценариев:
Метод | Малые датасеты <br>(<100K строк) | Средние датасеты <br>(100K-1M строк) | Большие датасеты <br>(>1M строк) | Особенности |
---|---|---|---|---|
df['col'].nunique() | Очень быстро | Быстро | Средне | Наиболее удобный API, оптимизирован для pandas |
len(set(df['col'])) | Быстро | Средне | Быстро для числовых данных | Хорошо для целых чисел, работает медленнее с объектами |
len(np.unique(df['col'])) | Быстро | Быстро | Быстрее nunique() для числовых данных | Строго типизирован, не работает с разнородными типами |
df['col'].value_counts().shape[0] | Средне | Медленно | Очень медленно | Избыточен, если нужно только количество |
len(df.drop_duplicates(['col'])) | Медленно | Очень медленно | Крайне медленно | Наименее эффективный для простого подсчета |
Для экстремально больших объемов данных можно использовать дополнительные техники оптимизации:
- Уменьшение использования памяти с категориальными типами:
# Преобразование в категориальный тип перед подсчетом
df_large['category'] = df_large['category'].astype('category')
category_unique = df_large['category'].nunique()
- Использование параллельных вычислений с dask:
import dask.dataframe as dd
# Преобразование в dask DataFrame
dask_df = dd.from_pandas(df_large, npartitions=4)
unique_count = dask_df['id'].nunique().compute()
- Применение методов приближенного подсчета для экстремальных объемов:
from datasketch import HyperLogLog
# Приближенный подсчет уникальных значений (для очень больших наборов данных)
hll = HyperLogLog()
for value in df_large['id'].values:
hll.update(str(value).encode('utf8'))
approximate_count = len(hll)
print(f"Приблизительное количество уникальных значений: {approximate_count}")
При оптимизации важно помнить несколько ключевых принципов:
- Всегда измеряйте время выполнения перед и после оптимизации
- Для строковых данных преобразование в категориальный тип может дать значительный прирост
- Параллельные вычисления оправданы только для очень больших объемов данных
- В крайних случаях можно жертвовать точностью ради скорости, используя вероятностные структуры данных
- Правильное использование индексов в базе данных до загрузки в pandas может сократить время обработки на порядки
В 2025 году появились новые возможности pandas для ускорения операций с уникальными значениями через использование адаптивных алгоритмов, которые автоматически выбирают оптимальный метод в зависимости от характеристик данных, но ручная настройка по-прежнему даёт наилучшие результаты для специфических задач. 🔧
Мы рассмотрели пять эффективных методов подсчета уникальных значений в pandas, каждый со своими сильными сторонами. Nunique() остается наиболее универсальным и компактным решением для повседневных задач. Value_counts() незаменим, когда нужна дополнительная информация о распределении данных. Drop_duplicates() предоставляет гибкость при работе с многомерными данными. А для высоконагруженных систем стоит присмотреться к оптимизированным методам с использованием numpy и структур на основе хеширования. Выбор правильного инструмента не только ускоряет аналитические процессы, но и открывает путь к более глубоким выводам — той самой трансформации данных в ценные решения, которая и составляет сущность современной аналитики.