pandy unikalne wartości wielu kolumn


144
df = pd.DataFrame({'Col1': ['Bob', 'Joe', 'Bill', 'Mary', 'Joe'],
                   'Col2': ['Joe', 'Steve', 'Bob', 'Bob', 'Steve'],
                   'Col3': np.random.random(5)})

Jaki jest najlepszy sposób na zwrócenie unikatowych wartości „Col1” i „Col2”?

Żądane wyjście to

'Bob', 'Joe', 'Bill', 'Mary', 'Steve'

4
Zobacz także unikalne kombinacje wartości w wybranych kolumnach w ramce danych pandy i policz dla innego, ale powiązanego pytania. Wybrana odpowiedź tam używadf1.groupby(['A','B']).size().reset_index().rename(columns={0:'count'})
Paul Rougieux

Odpowiedzi:


212

pd.unique zwraca unikatowe wartości z tablicy wejściowej lub kolumny lub indeksu DataFrame.

Dane wejściowe tej funkcji muszą być jednowymiarowe, więc trzeba będzie połączyć wiele kolumn. Najprostszym sposobem jest wybranie żądanych kolumn, a następnie wyświetlenie wartości w spłaszczonej tablicy NumPy. Cała operacja wygląda tak:

>>> pd.unique(df[['Col1', 'Col2']].values.ravel('K'))
array(['Bob', 'Joe', 'Bill', 'Mary', 'Steve'], dtype=object)

Zauważ, że ravel()jest to metoda tablicowa, która zwraca widok (jeśli to możliwe) tablicy wielowymiarowej. Argument 'K'mówi metodzie, aby spłaszczyła tablicę w kolejności, w jakiej elementy są przechowywane w pamięci (pandy zazwyczaj przechowują podstawowe tablice w kolejności ciągłej w języku Fortran ; kolumny przed wierszami). Może to być znacznie szybsze niż użycie domyślnej kolejności „C” metody.


Alternatywnym sposobem jest wybranie kolumn i przekazanie ich do np.unique:

>>> np.unique(df[['Col1', 'Col2']].values)
array(['Bill', 'Bob', 'Joe', 'Mary', 'Steve'], dtype=object)

Nie ma potrzeby używania ravel()tutaj, ponieważ metoda obsługuje tablice wielowymiarowe. Mimo to prawdopodobnie będzie to wolniejsze niż pd.uniquew przypadku użycia algorytmu opartego na sortowaniu zamiast tablicy hashy do identyfikacji unikalnych wartości.

Różnica w szybkości jest znacząca w przypadku większych ramek DataFrame (zwłaszcza jeśli istnieje tylko kilka unikalnych wartości):

>>> df1 = pd.concat([df]*100000, ignore_index=True) # DataFrame with 500000 rows
>>> %timeit np.unique(df1[['Col1', 'Col2']].values)
1 loop, best of 3: 1.12 s per loop

>>> %timeit pd.unique(df1[['Col1', 'Col2']].values.ravel('K'))
10 loops, best of 3: 38.9 ms per loop

>>> %timeit pd.unique(df1[['Col1', 'Col2']].values.ravel()) # ravel using C order
10 loops, best of 3: 49.9 ms per loop

2
Jak odzyskać ramkę danych zamiast tablicy?
Lisle

1
@Lisle: obie metody zwracają tablicę NumPy, więc będziesz musiał utworzyć ją ręcznie, np pd.DataFrame(unique_values). Nie ma dobrego sposobu na bezpośrednie odzyskanie ramki DataFrame.
Alex Riley

@Lisle, odkąd użył pd.unique, zwraca numpy.ndarray jako końcowe wyjście. Czy o to pytałeś?
Ash Upadhyay,

1
@Lisle, może ten df = df.drop_duplicates (podzbiór = ['C1', 'C2', 'C3'])?
łaskotanie ziemniaków

14

Skonfigurowałem a DataFramez kilkoma prostymi ciągami w jego kolumnach:

>>> df
   a  b
0  a  g
1  b  h
2  d  a
3  e  e

Możesz konkatenować interesujące Cię kolumny i wywołać uniquefunkcję:

>>> pandas.concat([df['a'], df['b']]).unique()
array(['a', 'b', 'd', 'e', 'g', 'h'], dtype=object)

7
In [5]: set(df.Col1).union(set(df.Col2))
Out[5]: {'Bill', 'Bob', 'Joe', 'Mary', 'Steve'}

Lub:

set(df.Col1) | set(df.Col2)


1

Brak pandasrozwiązania: użycie set ().

import pandas as pd
import numpy as np

df = pd.DataFrame({'Col1' : ['Bob', 'Joe', 'Bill', 'Mary', 'Joe'],
              'Col2' : ['Joe', 'Steve', 'Bob', 'Bob', 'Steve'],
               'Col3' : np.random.random(5)})

print df

print set(df.Col1.append(df.Col2).values)

Wynik:

   Col1   Col2      Col3
0   Bob    Joe  0.201079
1   Joe  Steve  0.703279
2  Bill    Bob  0.722724
3  Mary    Bob  0.093912
4   Joe  Steve  0.766027
set(['Steve', 'Bob', 'Bill', 'Joe', 'Mary'])

1

dla tych z nas, którzy kochają wszystko, co pandy, zastosuj i oczywiście funkcje lambda:

df['Col3'] = df[['Col1', 'Col2']].apply(lambda x: ''.join(x), axis=1)

1

oto inny sposób


import numpy as np
set(np.concatenate(df.values))

0
list(set(df[['Col1', 'Col2']].as_matrix().reshape((1,-1)).tolist()[0]))

Dane wyjściowe to [„Mary”, „Joe”, „Steve”, „Bob”, „Bill”]

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.