Jak „wybrać odrębne” w wielu kolumnach ramek danych w pandach?

101

Szukam sposobu, aby zrobić odpowiednik SQL

SELECT DISTINCT col1, col2 FROM dataframe_table

Pandy SQL porównanie nie ma nic na temat distinct.

.unique() działa tylko dla jednej kolumny, więc przypuszczam, że mógłbym połączyć kolumny lub umieścić je na liście / krotce i porównać w ten sposób, ale wydaje się, że pandy powinny robić coś w bardziej natywny sposób.

Czy brakuje mi czegoś oczywistego, czy nie ma sposobu, aby to zrobić?

Jody
źródło
Musiałbyś zrobić coś takiego, df.apply(pd.Series.unique)ale to nie zadziała, jeśli liczba unikalnych wartości różni się w kolumnach, więc musisz skonstruować dyktowanie nazw kolumn jako kluczy i unikalnych wartości jako wartości
EdChum
Dokumentacja SO
user2314737,

Odpowiedzi:

172

Możesz użyć tej drop_duplicatesmetody, aby uzyskać unikalne wiersze w 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

Możesz również podać subsetargument słowa kluczowego, jeśli chcesz używać tylko niektórych kolumn do określenia niepowtarzalności. Zobacz docstring .

joris
źródło
4
Być może warto zauważyć, że df.drop_duplicates()domyślnie nie jest metodą inplace, więc zwraca nową ramkę DataFrame (pozostawiając dfniezmienioną). Jest to dość standardowe zachowanie, ale nadal może być przydatne.
evophage
13

Próbowałem różnych rozwiązań. Najpierw było:

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

i działa dobrze dla danych niebędących obiektami Innym sposobem na zrobienie tego i uniknięcie błędów (dla kolumn typu obiektu) jest zastosowanie drop_duplicates ()

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

Możesz również użyć SQL, aby to zrobić, ale w moim przypadku działało to bardzo wolno:

from pandasql import sqldf
q="""SELECT DISTINCT col1, col2 FROM df;"""
pysqldf = lambda q: sqldf(q, globals())
a_df = pysqldf(q)
Portfel Yury
źródło
7

Nie ma uniquemetody dla df, jeśli liczba unikalnych wartości dla każdej kolumny byłaby taka sama, zadziałałyby następujące działania: df.apply(pd.Series.unique)ale jeśli nie, otrzymasz błąd. Innym podejściem byłoby przechowywanie wartości w dictwie, który jest wpisany w nazwę kolumny:

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
źródło
czy można sprawdzić unikalność dla wielu kolumn?
Anoop D
Otrzymałem odpowiedź z innego pytania SO przy użyciu numpynp.unique(df[['column1','column2']].values)
Anoop D
6

Aby rozwiązać podobny problem, używam groupby:

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

To, czy będzie to właściwe, będzie zależeć od tego, co chcesz zrobić z wynikiem (w moim przypadku chciałem tylko odpowiednika tego, COUNT DISTINCTco pokazano).

ncoghlan
źródło
-1

Możesz wziąć zestawy kolumn i po prostu odjąć mniejszy zestaw od większego zestawu:

distinct_values = set(df['a'])-set(df['b'])
dorante
źródło