numpy.unique()で重複要素のない配列を生成する

numpy.unique()で重複要素のない配列を生成する

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]