Come "selezionare distinti" su più colonne di frame di dati nei panda?


101

Sto cercando un modo per eseguire l'equivalente di SQL

SELECT DISTINCT col1, col2 FROM dataframe_table

Il confronto sql panda non ha nulla a che fare distinct.

.unique() funziona solo per una singola colonna, quindi suppongo di poter concatenare le colonne o metterle in una lista / tupla e confrontarle in questo modo, ma questo sembra qualcosa che i panda dovrebbero fare in un modo più nativo.

Mi manca qualcosa di ovvio o non c'è modo di farlo?


Dovresti fare qualcosa del genere, df.apply(pd.Series.unique)ma questo non funzionerà se il numero di valori univoci varia tra le colonne, quindi dovresti costruire un dict dei nomi delle colonne come chiavi e dei valori univoci come valori
EdChum

Risposte:


172

Puoi utilizzare il drop_duplicatesmetodo per ottenere le righe univoche in 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

Puoi anche fornire l' subsetargomento della parola chiave se desideri utilizzare solo determinate colonne per determinare l'unicità. Vedi la docstring .


3
Forse vale la pena notare che df.drop_duplicates()per impostazione predefinita non è un metodo inplace, quindi restituisce un nuovo DataFrame (lasciando dfinvariato). Questo è un comportamento abbastanza standard, ma può comunque essere utile segnalarlo.
evophage

13

Ho provato diverse soluzioni. Il primo è stato:

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

e funziona bene per i dati non oggetto Un altro modo per farlo ed evitare errori (per il tipo di colonne oggetto) è applicare drop_duplicates ()

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

Puoi anche usare SQL per farlo, ma nel mio caso ha funzionato molto lentamente:

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

7

Non esiste un uniquemetodo per un df, se il numero di valori univoci per ciascuna colonna fosse lo stesso, allora funzionerebbe quanto segue: df.apply(pd.Series.unique)ma in caso contrario, verrà visualizzato un errore. Un altro approccio sarebbe quello di memorizzare i valori in un dict che è digitato sul nome della colonna:

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)}

è possibile verificare l'unicità per più colonne?
Anoop D

Ho ottenuto la risposta da un'altra domanda SO utilizzando numpynp.unique(df[['column1','column2']].values)
Anoop D

6

Per risolvere un problema simile, sto usando groupby:

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

Se ciò è appropriato dipenderà da ciò che vuoi fare con il risultato, però (nel mio caso, volevo solo l'equivalente di COUNT DISTINCTcome mostrato).



-1

Puoi prendere i set di colonne e sottrarre semplicemente il set più piccolo dal set più grande:

distinct_values = set(df['a'])-set(df['b'])
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.