Нашли ошибку?
среднийNumPy 2.5.3

Уникальные значения и множества

Список различных значений с частотами, проверка вхождения и операции над множествами — пересечение, объединение, разность.

Нужно знать:СортировкаБулевы маски

Содержание статьи

Коротко

  • np.unique(a) — отсортированные уникальные значения.
  • return_counts=True добавляет частоты, return_inverse=True — номер уникального значения для каждого элемента (удобно для кодирования категорий), return_index=True — где значение встретилось впервые.
  • axis=0 ищет уникальные строки двумерного массива.
  • Короткие функции (NumPy 2): unique_values, unique_counts, unique_inverse, unique_all.
  • np.isin(a, b) — маска «элемент a есть в b». Множества: intersect1d, union1d, setdiff1d, setxor1d — результат отсортирован и без повторов.

Синтаксис

np.unique(a, return_index=False, return_inverse=False,
        return_counts=False, axis=None)
np.unique_counts(a)          # → (values, counts)
np.isin(a, b, invert=False)
np.intersect1d(a, b), np.union1d(a, b)
np.setdiff1d(a, b), np.setxor1d(a, b)

Параметры

ПараметрЧто делаетПо умолчанию
return_countsвернуть число вхождений каждого значенияFalse
return_inverseвернуть индексы, по которым из уникальных восстанавливается исходный массивFalse
return_indexвернуть индекс первого вхожденияFalse
axisискать уникальные срезы вдоль оси, например строки при axis=0None
invertв isin: True — маска «нет в b»False

Примеры

Данные для примеровиспользуются во всех примерах ниже
orders = np.array(["чай", "кофе", "чай", "сок", "кофе", "чай"])
Уникальные значения
np.unique(orders)                             # уникальные значения, отсортированные
Вывод
array(['кофе', 'сок', 'чай'], dtype='<U4')
Частоты и самое частое значение
values, counts = np.unique(orders, return_counts=True)
print(values)
print(counts)
values[counts.argmax()]                       # самое частое
Вывод
['кофе' 'сок' 'чай']
[2 1 3]
np.str_('чай')
Коды значений
values, codes = np.unique(orders, return_inverse=True)
print(codes)                                  # номер значения для каждого элемента
values[codes]                                 # восстановить исходный массив
Вывод
[2 0 2 1 0 2]
array(['чай', 'кофе', 'чай', 'сок', 'кофе', 'чай'], dtype='<U4')
Функции unique_values и unique_counts
print(np.unique_values(orders))
np.unique_counts(orders)
Вывод
['кофе' 'сок' 'чай']
UniqueCountsResult(values=array(['кофе', 'сок', 'чай'], dtype='<U4'), counts=array([2, 1, 3]))
Уникальные строки
pairs = np.array([[1, 2], [3, 4], [1, 2]])
np.unique(pairs, axis=0)                      # уникальные строки
Вывод
array([[1, 2],
       [3, 4]])
Проверка вхождения
menu = np.array(["чай", "кофе"])
print(np.isin(orders, menu))
orders[~np.isin(orders, menu)]                # заказы не из меню
Вывод
[ True  True  True False  True  True]
array(['сок'], dtype='<U4')
Операции над множествами
a = np.array([1, 2, 3, 4])
b = np.array([3, 4, 5])
print(np.intersect1d(a, b))                   # в обоих
print(np.union1d(a, b))                       # хотя бы в одном
print(np.setdiff1d(a, b))                     # в a, но не в b
np.setxor1d(a, b)                             # ровно в одном
Вывод
[3 4]
[1 2 3 4 5]
[1 2]
array([1, 2, 5])

Подводные камни

NaN в unique

np.unique считает все NaN одним значением, хотя NaN != NaN. Чтобы каждый NaN остался отдельным, передайте equal_nan=False.

unique с NaN
np.unique(np.array([1.0, np.nan, 2.0, np.nan]))   # NaN схлопываются в один
Вывод
array([ 1.,  2., nan])
equal_nan=False
np.unique(np.array([1.0, np.nan, 2.0, np.nan]), equal_nan=False)
Вывод
array([ 1.,  2., nan, nan])

np.in1d удалён

Вызов np.in1dошибка: AttributeError
np.in1d(orders, menu)
Ошибка
AttributeError: module 'numpy' has no attribute 'in1d'