1. ホーム
  2. python

[解決済み] pandasの一意な値複数の列

2022-03-16 15:09:39

質問

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

Col1'と'Col2'のユニークな値を返すには、どのような方法が良いでしょうか?

望ましい出力は

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

解決方法は?

pd.unique は、入力された配列、またはDataFrameのカラムやインデックスから一意の値を返します。

この関数への入力は一次元である必要があるため、複数の列を組み合わせる必要があります。最も簡単な方法は、必要な列を選択し、その値をNumPyのフラット化された配列で表示することです。全体の操作はこのようになります。

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

なお ravel() は配列メソッドで、多次元配列のビューを (可能であれば) 返します。引数 'K' は、メモリに格納されている順番に配列を平坦化するようにメソッドに指示します(pandasは通常、基礎となる配列を Fortran-連続した順序 列が行の前にある)。これは、このメソッドのデフォルトの 'C' 順序を使用するよりも大幅に高速化される可能性があります。


別の方法として、カラムを選択して np.unique :

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

を使用する必要はありません。 ravel() このメソッドは多次元配列を処理するためです。それでも、これは pd.unique は一意な値を特定するためにハッシュテーブルではなく、ソートベースのアルゴリズムを使用しているためです。

この速度の差は、大きなDataFrameの場合(特にユニークな値が数個しかない場合)に顕著になります。

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