Панды уникальные значения нескольких столбцов
df = pd.DataFrame({'Col1': ['Bob', 'Joe', 'Bill', 'Mary', 'Joe'],
'Col2': ['Joe', 'Steve', 'Bob', 'Bob', 'Steve'],
'Col3': np.random.random(5)})
Каков наилучший способ вернуть уникальные значения Col1 и Col2?
Желаемый результат
'Bob', 'Joe', 'Bill', 'Mary', 'Steve'
13 ответов
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
Я настроил DataFrame
с несколькими простыми строками в столбцах:
>>> df
a b
0 a g
1 b h
2 d a
3 e e
Вы можете объединить интересующие вас столбцы и позвонить unique
функция:
>>> pandas.concat([df['a'], df['b']]).unique()
array(['a', 'b', 'd', 'e', 'g', 'h'], dtype=object)
In [5]: set(df.Col1).union(set(df.Col2))
Out[5]: {'Bill', 'Bob', 'Joe', 'Mary', 'Steve'}
Или же:
set(df.Col1) | set(df.Col2)
Обновленное решение, использующее numpy v1.13 +, требует указания оси в np.unique, если используется несколько столбцов, в противном случае массив неявно выравнивается.
import numpy as np
np.unique(df[['col1', 'col2']], axis=0)
Это изменение было введено в ноябре 2016 года: https://github.com/numpy/numpy/commit/1f764dbff7c496d6636dc0430f083ada9ff4e4be
Для тех из нас, кто любит все, что касается панд, применяются и, конечно, лямбда-функции:
df['Col3'] = df[['Col1', 'Col2']].apply(lambda x: ''.join(x), axis=1)
Вот еще один способ
import numpy as np
set(np.concatenate(df.values))
Не -pandas
Решение: с помощью set().
import pandas as pd
import numpy as np
df = pd.DataFrame({'Col1' : ['Bob', 'Joe', 'Bill', 'Mary', 'Joe'],
'Col2' : ['Joe', 'Steve', 'Bob', 'Bob', 'Steve'],
'Col3' : np.random.random(5)})
print df
print set(df.Col1.append(df.Col2).values)
Выход:
Col1 Col2 Col3
0 Bob Joe 0.201079
1 Joe Steve 0.703279
2 Bill Bob 0.722724
3 Mary Bob 0.093912
4 Joe Steve 0.766027
set(['Steve', 'Bob', 'Bill', 'Joe', 'Mary'])
Вы можете использоватьstack
объединить несколько столбцов иdrop_duplicates
чтобы найти уникальные значения:
df[['Col1', 'Col2']].stack().drop_duplicates().tolist()
Выход:
['Bob', 'Joe', 'Steve', 'Bill', 'Mary']
df = pd.DataFrame({'Col1': ['Bob', 'Joe', 'Bill', 'Mary', 'Joe'],
'Col2': ['Joe', 'Steve', 'Bob', 'Bob', 'Steve'],
'Col3': np.random.random(5)})
Если ваш вопрос заключается в том, как получить уникальные значения каждого столбца по отдельности?
Сортировка меток столбцов в списке
column_labels = ['Col1', 'Col2']
Создать пустой dict
unique_dict = {}
Перебрать выбранные столбцы, чтобы получить их уникальные значения.
for column_label in column_labels:
unique_values = df[column_label].unique()
unique_dict.update({column_label: unique_values})
unique_ser = pd.Series(unique_dict)
print(unique_ser)
Получите список уникальных значений по списку имен столбцов:
cols = ['col1','col2','col3','col4']
unique_l = pd.concat([df[col] for col in cols]).unique()
list(set(df[['Col1', 'Col2']].as_matrix().reshape((1,-1)).tolist()[0]))
Результатом будет ['Мэри', 'Джо', 'Стив', 'Боб', 'Билл']
import pandas as pd
df= pd.DataFrame({'col1':["a","a","b","c","c","d"],'col2':
["x","x","y","y","z","w"],'col3':[1,2,2,3,4,2]})
df
выход
col1 col2 col3
0 a x 1
1 a x 2
2 b y 2
3 c y 3
4 c z 4
5 d w 2
чтобы получить уникальные значения из всех столбцов
a={}
for i in range(df.shape[1]) :
j=df.columns[i]
a[j] = df.iloc[:,i].unique()
for p,q in a.items():
print( f"unique value in {p} are {list(q)} ")
выход
unique value in col1 are ['a', 'b', 'c', 'd']
unique value in col2 are ['x', 'y', 'z', 'w']
unique value in col3 are [1, 2, 3, 4]