¿Cómo "seleccionar distintos" en varias columnas de marcos de datos en pandas?

101

Estoy buscando una forma de hacer el equivalente al SQL

SELECT DISTINCT col1, col2 FROM dataframe_table

La comparación de pandas sql no tiene nada sobre distinct.

.unique() solo funciona para una sola columna, así que supongo que podría concaminar las columnas, o ponerlas en una lista / tupla y comparar de esa manera, pero esto parece algo que los pandas deberían hacer de una manera más nativa.

¿Me estoy perdiendo algo obvio o no hay forma de hacer esto?

Jody
fuente
Tendría que hacer algo como, df.apply(pd.Series.unique)pero esto no funcionará si el número de valores únicos varía entre las columnas, por lo que tendrá que construir un dictado de los nombres de las columnas como claves y los valores únicos como valores
EdChum
SO Documentation
user2314737

Respuestas:

172

Puede usar el drop_duplicatesmétodo para obtener filas únicas en un 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

También puede proporcionar el subsetargumento de la palabra clave si solo desea utilizar determinadas columnas para determinar la unicidad. Consulte la cadena de documentación .

joris
fuente
3
Posiblemente valga la pena señalar que df.drop_duplicates()de forma predeterminada no es un método in situ, por lo que devuelve un nuevo DataFrame ( dfsin cambios). Este es un comportamiento bastante estándar, pero aún puede ser útil señalarlo.
evophage
13

Probé diferentes soluciones. Primero fue:

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

y funciona bien para datos que no son de objetos. Otra forma de hacer esto y evitar errores (para el tipo de columnas de objetos) es aplicar drop_duplicates ()

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

También puede usar SQL para hacer esto, pero funcionó muy lento en mi caso:

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

No existe un uniquemétodo para un df, si el número de valores únicos para cada columna fuera el mismo, lo siguiente funcionaría: df.apply(pd.Series.unique)pero si no, obtendrá un error. Otro enfoque sería almacenar los valores en un dictado que se ingresa en el nombre de la columna:

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
fuente
¿Es posible comprobar si es único para varias columnas?
Anoop D
Obtuve la respuesta de otra pregunta SO usando numpynp.unique(df[['column1','column2']].values)
Anoop D
6

Para resolver un problema similar, estoy usando groupby:

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

Sin embargo, si eso es apropiado dependerá de lo que quieras hacer con el resultado (en mi caso, solo quería el equivalente de lo COUNT DISTINCTque se muestra).

ncoghlan
fuente
-1

Puede tomar los conjuntos de columnas y simplemente restar el conjunto más pequeño del conjunto más grande:

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