¿Cómo “seleccionar distintos” en múltiples columnas de marcos de datos en pandas?

3 minutos de lectura

avatar de usuario
Jody

Estoy buscando una manera de hacer el equivalente al SQL

SELECT DISTINCT col1, col2 FROM dataframe_table

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

.unique() solo funciona para una sola columna, así que supongo que podría concatenar las columnas, o ponerlas en una lista/tupla y compararlas 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 hacerlo?

  • Tendrías que hacer algo como df.apply(pd.Series.unique) pero esto no funcionará si la cantidad de valores únicos varía entre las columnas, por lo que tendría que construir un dict de los nombres de columna como claves y los valores únicos como valores

    – EdChum

    29 mayo 2015 a las 13:25


  • SO Documentación

    – usuario2314737

    3 de diciembre de 2016 a las 12:15

Puedes usar el drop_duplicates método para obtener las 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 la subset argumento de palabra clave si solo desea usar ciertas columnas para determinar la unicidad. Ver el cadena de documentación.

  • Posiblemente vale la pena señalar que df.drop_duplicates() por defecto no es un método en el lugar, por lo que devuelve un nuevo DataFrame (dejando df sin alterar). Este es un comportamiento bastante estándar, pero aún puede ser útil señalarlo.

    – evofago

    4 de febrero de 2019 a las 21:29


avatar de usuario
Billetera Yury

He probado diferentes soluciones. Primero fue:

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

y funciona bien para datos no objeto. 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)

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 quiera hacer con el resultado (en mi caso, solo quería el equivalente de COUNT DISTINCT como se muestra).

No hay unique mé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)}

avatar de usuario
Naiara Andrade

creo que uso drop duplicate a veces no será tan útil dependiendo del marco de datos.

Encontré esto:

[in] df['col_1'].unique()
[out] array(['A', 'B', 'C'], dtype=object)

¡Y funcionó para mí!

https://riptutorial.com/es/pandas/ejemplo/26077/seleccionar-filas-distintas-en-el-marco-de-datos

avatar de usuario
dorado

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

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

¿Ha sido útil esta solución?