Ответ 1
pd.unique
возвращает уникальные значения из входного массива или столбца или индекса DataFrame.
Входные данные для этой функции должны быть одномерными, поэтому необходимо объединить несколько столбцов. Самый простой способ - выбрать нужные столбцы, а затем просмотреть значения в плоском массиве NumPy. Вся операция выглядит так:
>>> pd.unique(df[['Col1', 'Col2']].values.ravel('K'))
array(['Bob', 'Joe', 'Bill', 'Mary', 'Steve'], dtype=object)
Обратите внимание, что ravel()
- это метод массива, который возвращает представление (если возможно) многомерного массива. Аргумент 'K'
указывает методу выравнивать массив в порядке, в котором элементы хранятся в памяти (pandas обычно хранит базовые массивы в смежном с Фортраном порядке; столбцы перед строками). Это может быть значительно быстрее, чем при использовании метода "C" по умолчанию.
Альтернативный способ - выбрать столбцы и передать их в np.unique
:
>>> np.unique(df[['Col1', 'Col2']].values)
array(['Bill', 'Bob', 'Joe', 'Mary', 'Steve'], dtype=object)
Здесь нет необходимости использовать ravel()
как метод обрабатывает многомерные массивы. Тем не менее, это, вероятно, будет медленнее, чем pd.unique
поскольку он использует алгоритм на основе сортировки, а не хеш-таблицу для идентификации уникальных значений.
Разница в скорости значительна для больших DataFrames (особенно если есть только несколько уникальных значений):
>>> df1 = pd.concat([df]*100000, ignore_index=True) # DataFrame with 500000 rows
>>> %timeit np.unique(df1[['Col1', 'Col2']].values)
1 loop, best of 3: 1.12 s per loop
>>> %timeit pd.unique(df1[['Col1', 'Col2']].values.ravel('K'))
10 loops, best of 3: 38.9 ms per loop
>>> %timeit pd.unique(df1[['Col1', 'Col2']].values.ravel()) # ravel using C order
10 loops, best of 3: 49.9 ms per loop