Como “selecionar distintos” em várias colunas de quadro de dados em pandas?

101

Estou procurando uma maneira de fazer o equivalente ao SQL

SELECT DISTINCT col1, col2 FROM dataframe_table

A comparação pandas sql não tem nada sobre distinct.

.unique() só funciona para uma única coluna, então suponho que poderia concatá-las ou colocá-las em uma lista / tupla e comparar dessa forma, mas isso parece algo que os pandas deveriam fazer de uma forma mais nativa.

Estou perdendo algo óbvio ou não há como fazer isso?

Jody
fonte
Você teria que fazer algo como, df.apply(pd.Series.unique)mas isso não funcionará se o número de valores únicos variar nas colunas, então você teria que construir um dicionário dos nomes das colunas como chaves e os valores únicos como os valores
EdChum
Documentação do SO
user2314737

Respostas:

172

Você pode usar o drop_duplicatesmétodo para obter as linhas exclusivas em um DataFrame:

In [29]: df = pd.DataFrame({'a':[1,2,1,2], 'b':[3,4,3,5]})

In [30]: df
Out[30]:
   a  b
0  1  3
1  2  4
2  1  3
3  2  5

In [32]: df.drop_duplicates()
Out[32]:
   a  b
0  1  3
1  2  4
3  2  5

Você também pode fornecer o subsetargumento de palavra - chave se quiser usar apenas certas colunas para determinar a exclusividade. Veja a docstring .

Joris
fonte
3
Possivelmente, é importante notar que, df.drop_duplicates()por padrão, não é um método local, portanto, retorna um novo DataFrame (deixando dfinalterado). Este é um comportamento bastante padrão, mas ainda pode ser útil apontar.
evophage
13

Tentei soluções diferentes. Primeiro foi:

a_df=np.unique(df[['col1','col2']], axis=0)

e funciona bem para dados não objeto Outra maneira de fazer isso e evitar erros (para tipo de colunas de objeto) é aplicar drop_duplicates ()

a_df=df.drop_duplicates(['col1','col2'])[['col1','col2']]

Você também pode usar SQL para fazer isso, mas funcionou muito devagar no meu caso:

from pandasql import sqldf
q="""SELECT DISTINCT col1, col2 FROM df;"""
pysqldf = lambda q: sqldf(q, globals())
a_df = pysqldf(q)
Carteira Yury
fonte
7

Não há uniquemétodo para um df. Se o número de valores exclusivos para cada coluna fosse o mesmo, o seguinte funcionaria: df.apply(pd.Series.unique)mas se não, você obterá um erro. Outra abordagem seria armazenar os valores em um dicionário que é digitado no nome da coluna:

In [111]:
df = pd.DataFrame({'a':[0,1,2,2,4], 'b':[1,1,1,2,2]})
d={}
for col in df:
    d[col] = df[col].unique()
d

Out[111]:
{'a': array([0, 1, 2, 4], dtype=int64), 'b': array([1, 2], dtype=int64)}
EdChum
fonte
é possível verificar se há colunas exclusivas para várias?
Anoop D
Obtive a resposta de outra pergunta do SO usando numpynp.unique(df[['column1','column2']].values)
Anoop D
6

Para resolver um problema semelhante, estou usando groupby:

print(f"Distinct entries: {len(df.groupby(['col1', 'col2']))}")

Se isso for apropriado, dependerá do que você deseja fazer com o resultado (no meu caso, eu só queria o equivalente COUNT DISTINCTao mostrado).

ncoghlan
fonte
-1

Você pode pegar os conjuntos de colunas e apenas subtrair o conjunto menor do conjunto maior:

distinct_values = set(df['a'])-set(df['b'])
dorante
fonte