numpy.unique()
numpy.unique() は受け取った配列から重複要素を取り除いて ユニークな要素 だけで構成される配列を返します (Python の set() に相当する関数です)。
numpy.unique(arr, return_index=False, return_inverse=False, return_counts=False, axis=None)
最初にオプション引数なしで 1 次元配列を渡してみます。
# NUMPY_UNIQUE_01
# In[1]
import numpy as np
# 配列xを定義
x = np.array([0, 5, 1, 3, 5, 0, 2])
# xの重複要素を取り除く
a = np.unique(x)
print(a)
[0 1 2 3 5]
return_index を True に設定すると、ユニーク配列に加えて、各要素の抽出位置 (インデクス) を示す配列も返します。
# In[2]
# ユニーク配列と、抽出要素のインデクスを取得
b = np.unique(x, return_index=True)
print(b)
(array([0, 1, 2, 3, 5]), array([0, 2, 6, 3, 1], dtype=int64))
この実行結果は、もとの配列の [0, 2, 6, 3, 1] の位置から要素を取ってユニーク配列 [0, 1, 2, 3, 5] が生成されたことを意味しています。
return_inverse に True を渡すと、ユニーク配列に加えて、ユニーク配列をもとの配列に復元するインデクス配列を取得します。
# In[3]
# ユニーク配列と、もとの配列に復元するインデクス配列を取得
c, d = np.unique(x, return_inverse=True)
print(c)
print(d)
[0 1 2 3 5] [0 4 1 3 4 0 2]
すなわち、c[d] でもとの配列 x を復元できます。
# In[4]
# 配列xを復元
print(c[d])
[0 5 1 3 5 0 2]
return_counts に True を渡すと、ユニーク配列に加えて、もとの配列にそれぞれの要素が何個ずつ含まれていたかを示す配列を返します。
# In[5]
# ユニーク配列に加えて、
# もとの配列に各要素が何個ずつ含まれていたかを示す配列を取得
e, f = np.unique(x, return_counts=True)
print(e)
print(f)
[0 1 2 3 5] [2 1 1 1 2]
axis を指定せずに numpy.uniqe() に 2 次元配列を渡すと、1 次元にフラット化されたユニーク配列が返ります。
# NUMPY_UNIQUE_02
# In[1]
import numpy as np
# 配列yを定義
y = np.array([[0, 1, 1],
[0, 1, 1],
[1, 0, 1]])
# yをフラットにしてユニーク配列を生成
g = np.unique(y)
print(g)
[0 1]
axis=0 を渡すと、重複する行を省いて新しい配列を生成します。
# In[2]
# 行が重複しない配列を生成
h = np.unique(y, axis=0)
print(h)
[[0 1 1] [1 0 1]]
axis=1 を渡すと、重複する列を取り除いた新しい配列を生成します。
# In[3]
# 配列zを作成
z = np.array([[9, 9, 0, 1],
[0, 0, 1, 1],
[9, 9, 0, 0]])
# 列が重複しな配列を生成
i = np.unique(z, axis=1)
print(i)
[[0 1 9] [1 1 0] [0 0 9]]
return_index=True と axis=1 を組合わせると、重複列を取り除いたユニーク配列と、抽出した列のインデクス配列をタプルで返します。
# In[4]
# ユニーク配列と、抽出した列のインデクス配列を取得
j, k = np.unique(z, return_index=True, axis=1)
print(j)
print(k)
[[0 1 9] [1 1 0] [0 0 9]] [2 3 0]
In[2] プログラムとその実行結果が分離されていません。
In[2] プログラムの実行結果の dtype=int32 は、Google Colabでは表示されませんでした。
申し訳ないです。
実行結果を囲む html タグがおかしかったです。
修正して分離しておきました。
確かに Google Colab では dtype が表示されませんね。x を生成するときに dtype を ‘int32′ などにすると、戻り値のユニーク配列のほうに dtype が含まれていました (Jupyter ではインデックス配列のほうに添えられます)。
――――――――――――――――――――――――――――――――
import numpy as np
x = np.array([0, 5, 1, 3, 5, 0, 2], dtype=’int32’)
b = np.unique(x, return_index=True)
print(b)
# (array([0, 1, 2, 3, 5], dtype=int32), array([0, 2, 6, 3, 1]))
――――――――――――――――――――――――――――――――
unique() 関数に渡した整数配列がデフォルトの型 (int64) だと表示されない仕組みになっているかもしれません。以下のコードを Jupyter Notebook で試してみると、dtype が int64 になってました (後で記事を修正しておきます)。
――――――――――――――――――――――――――――――――
import numpy as np
x = np.array([0, 5, 1, 3, 5, 0, 2])
b = np.unique(x, return_index=True)
print(b)
# (array([0, 1, 2, 3, 5]), array([0, 2, 6, 3, 1], dtype=int64))
―――――――――――――――――――――――――――――――
古い記事なので、NumPy のバージョンアップに伴う変更があったかもしれませんし、この記事を書いた時は 32 bit 版 Python を使っていたので、その影響かもしれません。ちなみに、現在の私の Jupyter Notebook の環境は以下の通りです。
Python 3.9.9
NumPy 1.21.4
Google Colab は現時点 (2023.2.18) で次の環境が提供されているようです。
Python 3.8.10
NumPy 1.21.6
numpy.unique を対話形式で説明します
ChatGPT に numpy.unique について、会話形式で説明してもらいました。
エンジニアA:ねえ、最近NumPyのunique関数について聞いたことある?
エンジニアB:うーん、どんな関数だろう?
エンジニアA:それは、NumPyの配列から一意な値を抽出するための関数なんだ。要するに、配列の中から重複する要素を取り除いて、ユニークな値のみを返すんだよ。
エンジニアB:なるほど、便利そうだね。使い方はどうやるの?
エンジニアA:使い方は簡単だよ。まず、NumPyをインポートしてから、np.uniqueという形で関数を呼び出すんだ。引数には対象の配列を指定するだけでいい。
エンジニアB:例えば、[2, 1, 3, 2, 1, 5]という配列があったら、どうやって重複を取り除くんだ?
エンジニアA:その場合は、np.unique([2, 1, 3, 2, 1, 5])と呼び出すだけでいい。すると、[1, 2, 3, 5]というユニークな値のリストが返ってくるよ。”
エンジニアB:なるほど、わかった。他に何かオプションとかあるの?
エンジニアA:そうだね、np.uniqueにはいくつかのオプションがあるよ。例えば、return_counts=Trueとすると、ユニークな値とその出現回数のタプルが返ってくるようになる。他にもいくつか便利なオプションがあるから、必要に応じてドキュメントを見るといいよ。
エンジニアB:ありがとう、分かりやすく教えてくれて助かったよ!これから使ってみるね。
エンジニアA:どういたしまして!頑張って使ってみてね。もし何かわからないことがあったら、いつでも聞いてくれると嬉しいな。