numpy.unique – 既存の配列から要素の重複をなくした配列を生成

numpy.uniqueは重複する値がない新しい配列を生成する関数です。さらに、それに加えて以下の3つを要素とする配列を取得することもできます。

  • 重複あり配列を重複なし配列として更新するためのインダイス
  • 重複なし配列から元の重複あり配列を復元するためのインダイス
  • 重複あり配列でのそれぞれの要素の出現回数

ここでは実際のコードで、これら全てを見ていきます。

目次

1. numpy.uniqueの使い方

それでは、まずはnumpy.uniqueの書き方から確認しましょう。

numpy.unique

np.unique()の書き方:

numpy.unique(arr, return_index=False, return_inverse=False, return_counts=False, axis=None)

パラメーター:

引数   解説
arr  array_like  配列を渡します。axisが指定されていない場合は、1次元配列化します。
return_index(optional)  bool   
これをTrueにすると、重複なし配列とともに、重複なし配列の値のインデックス(指定の軸に従う。axis=Noneの場合は1次元配列化した場合のインデックス)を要素とする配列を返します。このインダイスを使うと、元の重複あり配列を重複なし配列に上書きすることができます。
return_inverse(optional) bool これをTrueにすると、重複なし配列とともに、重複あり配列の値のインデックス(指定の軸に従う。axis=Noneの場合は1次元配列化した場合のインデックス)を要素とする配列を返します。このインダイスを使うと、重複なし配列から元の重複あり配列を復元することができます。
return_counts(optional) boolこれをTrueすると、重複なし配列とともに、それぞれの要素の元の配列における出現回数を要素とする配列を返します。
axis(optional) int or None関数を実行する軸を指定します。None(デフォルト値)では、配列は1次元化されます。

戻り値: 

unique: ndarray: 重複なし配列を戻します。
unique_indeices : ndarray(optional): 元の配列のそれぞれの値の最初のインデックスを要素とする配列を戻します。 
unique_inverse : ndarray(optional): 重複なし配列から、元の重複あり配列を復元するためのインデックスを要素とする配列を戻します。
unique_counts : ndarray(optional): 元の配列における、それぞれの要素の出現回数を要素とする配列を戻します。

一緒に確認したい関数:

  • numpy.lib.arraysetops

それでは、コードを見ながら使い方を確認していきましょう。

1.1. 重複する値のない配列を生成

numpy.uniqueに要素の値の重複がある配列を渡せば、重複のない配列を新しく生成します。

まず、以下のコードで重複する値がある配列を生成します。

In [1]:
'''  np.unique()で値の重複のない配列を生成  '''
import numpy as np
#  重複する値が存在する1次元配列を生成
arr = np.array([1, 1, 2, 3, 4, 5, 5, 5, 5, 5])
arr
Out[1]:
array([1, 1, 2, 3, 4, 5, 5, 5, 5, 5])

これをnumpy.uniqueに渡すと、値の重複のない配列を生成してくれます。

In [2]:
np.unique(arr)
Out[2]:
array([1, 2, 3, 4, 5])

多次元配列を渡した場合も、デフォルトでは新しい配列を1次元化して生成します。以下のコードは2次元配列の場合ですが、3次元配列でも4次元配列でも1次元配列化します。

In [3]:
'''  多次元配列を渡すと1次元配列として戻す  '''
#  2次元配列を生成
arr = np.array([[0, 1, 1], [2, 0, 0], [2, 3, 4]])
print('arr:\n', arr)
#   値の重複なしの配列を1次元配列として生成
uni = np.unique(arr)
print('uni:\n', uni)
arr:
 [[0 1 1]
 [2 0 0]
 [2 3 4]]
uni:
 [0 1 2 3 4]

1.2. 値が重複する軸をなくす(axis)

2次元配列以上の多次元配列で、オプション引数「axis=」を使うと、要素が全く同じ行や列をなくすことができます。

以下のコードは2次元配列の場合です。

2次元配列はaxis=0は「行」で、axis=1は「列」です。そのため、axis=0を指定すると値が重複する行をなくします。axis=1を指定すると値が重複する列をなくします。

In [4]:
'''  2次元配列でaxisを指定  '''
#  2次元配列を生成
arr = np.array([[0, 1, 1], [0, 1, 1], [2, 1, 1], [3, 1, 1]])
print('arr:\n', arr, '\n')

#   axis=0(要素が重複する行をなくす)
uni = np.unique(arr, axis=0)
print('axis=0:\n', uni, '\n')

#   axis=1(要素が重複する列をなくす))
uni = np.unique(arr, axis=1)
print('axis=1:\n', uni, '\n')
arr:
 [[0 1 1]
 [0 1 1]
 [2 1 1]
 [3 1 1]] 

axis=0:
 [[0 1 1]
 [2 1 1]
 [3 1 1]] 

axis=1:
 [[0 1]
 [0 1]
 [2 1]
 [3 1]] 

3次元配列の場合も見てみましょう。

3次元配列ではaxis=0は「奥行き」です。この場合、異なる奥行きで値が完全に重複する場合は、その重複を解消します。axis=1は「行」なので、値が重複する行をなくします。axis=2は「列」なので、値が重複する列をなくします。

In [5]:
'''  3次元配列でaxisを指定  '''
#  2次元配列を生成
arr = np.array([[[0, 1, 1], [0, 1, 1], [2, 1, 1]], [[0, 1, 1], [0, 1, 1], [2, 1, 1]]])
print('arr:\n', arr, '\n')

#   axis=0(要素が重複する奥行きをなくす)
uni = np.unique(arr, axis=0)
print('axis=0:\n', uni, '\n')

#   axis=1(要素が重複する行をなくす))
uni = np.unique(arr, axis=1)
print('axis=1:\n', uni, '\n')

#   axis=2(要素が重複する列をなくす))
uni = np.unique(arr, axis=2)
print('axis=2:\n', uni, '\n')
arr:
 [[[0 1 1]
  [0 1 1]
  [2 1 1]]

 [[0 1 1]
  [0 1 1]
  [2 1 1]]] 

axis=0:
 [[[0 1 1]
  [0 1 1]
  [2 1 1]]] 

axis=1:
 [[[0 1 1]
  [2 1 1]]

 [[0 1 1]
  [2 1 1]]] 

axis=2:
 [[[0 1]
  [0 1]
  [2 1]]

 [[0 1]
  [0 1]
  [2 1]]] 

1.3. 元の重複あり配列を重複なし配列に変換するインダイスを取得(return_index)

オプション引数で「return_index=True」と指定すると、重複なし配列と、値が重複する要素の一番最初のインデックスを取り出したインダイスの配列の2つが格納されたタプルを返します。

このインダイスの配列を使うと、元の重複あり配列を、重複なし配列として更新することができます。

まずは以下のコードをご確認下さい。

In [6]:
'''  return_indexを指定すると、要素のインデックスも返す '''
arr = np.array([1, 2, 1, 3, 4, 5, 3, 1, 6, 4, 7])
#  return_index=Trueで関数を実行
np.unique(arr, return_index=True)
Out[6]:
(array([1, 2, 3, 4, 5, 6, 7]), array([ 0,  1,  3,  4,  5,  8, 10]))

タプルの先頭の配列が重複なし配列で、2つめの配列がインダイスです。

次のように書くと、重複なし配列と、そのインダイス配列を、それぞれ別の変数に代入することができます。

In [7]:
'''  重複をなくした配列と、インダイスの配列を別の変数に代入'''
uni, indices = np.unique(arr, return_index=True)
print('重複をなくした配列: \n', uni)
print('インダイスの配列: \n', indices)
重複をなくした配列: 
 [1 2 3 4 5 6 7]
インダイスの配列: 
 [ 0  1  3  4  5  8 10]

これを用いて、以下のように書くと、元の配列を重複なし配列として上書きすることができますので覚えておきましょう。

In [8]:
'''  インダイスで重複あり配列を重複なし配列として上書きできる  '''
#  元の配列arrを上書き
arr = arr[indices]
arr
Out[8]:
array([1, 2, 3, 4, 5, 6, 7])

1.4. 重複なし配列を重複あり配列に戻すインダイスを取得(return_inverse)

オプション引数で「return_inverse=True」と指定すると、重複なし配列と、元の重複あり配列のインダイスが格納されたタプルを返します。

こちらのインダイスを使うと、重複なし配列を、元の重複あり配列に戻すことができます。

まずは以下のコードをご覧ください。

In [9]:
'''  return_inverseで元の配列を復元するためのインダイスを取得  '''
arr = np.array([1, 2, 1, 3, 4, 5, 3, 1, 6, 4, 7])
#  return_inverse=Trueで関数を実行
np.unique(arr, return_inverse=True)
Out[9]:
(array([1, 2, 3, 4, 5, 6, 7]), array([0, 1, 0, 2, 3, 4, 2, 0, 5, 3, 6]))

このインダイスを使って、重複なし配列を、元の重複あり配列に戻しているのが以下のコードです。

In [10]:
''' return_inverseで元の配列を復元 '''
#  変数uniと変数r_indicesにそれぞれ重複なし配列と、インダイスを代入
uni, r_indices = np.unique(arr, return_inverse=True)
#  重複なし配列
print(uni)
#  return_inverseのインデックス
print(r_indices)
#  重複なし配列から元の重複あり配列を復元
print(uni[r_indices])
[1 2 3 4 5 6 7]
[0 1 0 2 3 4 2 0 5 3 6]
[1 2 1 3 4 5 3 1 6 4 7]

1.5. それぞれの値の出現回数を取得

オプション引数で「return_counts=True」を指定すると、重複なし配列と、元の配列におけるそれぞれの値の出現回数を要素とした配列を格納するタプルを返します。

以下のコードでご確認ください。

In [11]:
'''  return_countsで重複要素の出現回数を取得  '''
arr = np.array([1, 2, 1, 3, 4, 5, 3, 1, 6, 4, 7])
#  return_counts=Trueで関数を実行
uni, counts = np.unique(arr, return_counts=True)
print('重複なし配列: \n', uni)
print('各要素の出現回数: \n', counts)
重複なし配列: 
 [1 2 3 4 5 6 7]
各要素の出現回数: 
 [3 1 2 2 1 1 1]

2. まとめ

以上が、numpy.uniqueの使い方です。

Python初心者におすすめのプログラミングスクール

「未経験からでもPythonを学べるプログラミングスクールを探しているけど、色々ありすぎてわからない」なら、次の3つのプログラミングスクールから選んでおけば間違いはありません。

Aidemy Premium:全くの初心者ができるだけ効率よく短期間で実務的に活躍できるAI人材になることを目的とした講座。キャリアカウンセリングや転職エージェントの紹介などの転職支援も充実しており、受講者の転職成功率が高い。

AIジョブカレPythonの基本をおさえた人が、実際に機械学習やディープラーニングを活用できるようになるための講座。転職補償型があるなどキャリア支援の内容が非常に手厚く、講師の質も最高クラス。コスパ最高。Python初心者用の対策講座もある。

データミックスプログラミング経験者のビジネスマンが、更なるキャリアアップのためにデータの処理方法を学んでデータサイエンティストになるための講座。転職だけでなく起業やフリーランスとして独立する人も多い。Python初心者用の対策講座もある。

特に、あなたが以下のような目標を持っているなら、この中から選んでおけば間違いはないでしょう。

・未経験からPythonエンジニアとして就職・転職したい
・AIエンジニアやデータサイエンティストとしてキャリアアップしたい
・起業やフリーランスを視野に入れたい

理由は「Python初心者のためのおすすめプログラミングスクール3選」で解説しています。



よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!

この記事を書いた人

コメント

コメントする

このサイトはスパムを低減するために Akismet を使っています。コメントデータの処理方法の詳細はこちらをご覧ください

目次
閉じる