MATLAB: unique(vs, 'rows') > Numpy: 実装 > v0.1,..v0.3 | np.where(unqs == alist)は符号に関係なくインデックスを返すようだ


動作環境
GeForce GTX 1070 (8GB)
ASRock Z170M Pro4S [Intel Z170chipset]
Ubuntu 16.04 LTS desktop amd64
TensorFlow v1.2.1
cuDNN v5.1 for Linux
CUDA v8.0
Python 3.5.2
IPython 6.0.0 -- An enhanced Interactive Python.
gcc (Ubuntu 5.4.0-6ubuntu1~16.04.4) 5.4.0 20160609
GNU bash, version 4.3.48(1)-release (x86_64-pc-linux-gnu)
scipy v0.19.1
geopandas v0.3.0
MATLAB R2017b (Home Edition)

関連

MATLAB

>> vs = [ 3 1 4; 1 5 9; 1 5 9; 2 6 5; ];
>> [res, ~, idx] = unique(vs, 'rows')

res =

     1     5     9
     2     6     5
     3     1     4


idx =

     3
     1
     1
     2

Numpy v0.1

参考: StackOverflow

answered Jan 11 '09 at 3:12
Alex

itemindex = numpy.where(array==item)

Numpyで実装してみた。

test_get_unique_rows_171225.py
import numpy as np

# on Python 3.5.2


def get_unique_rows(vs):
    unqs = np.unique(vs, axis=0)
    idxs = []
    for alist in vs:
        wrk = np.where(unqs == alist)
        idxs += [wrk[0][0]]
    return np.array(unqs), np.array(idxs)

vs = [
    [3, 1, 4],
    [1, 5, 9],
    [1, 5, 9],
    [2, 6, 5],
    ]
vs = np.array(vs)
res, idx = get_unique_rows(vs)
print('---original')
print(vs)
print('---unique')
print(res)
print('---index')
print(idx)

run
$ python3 test_get_unique_rows_171225.py 
---original
[[3 1 4]
 [1 5 9]
 [1 5 9]
 [2 6 5]]
---unique
[[1 5 9]
 [2 6 5]
 [3 1 4]]
---index
[2 0 0 1]

備考

MATLABとNumpyはインデックスの取り方が異なる。
MATLABは1始まり、Numpyは0始まり。
上記の実装はNumpyで0始まりのインデックスとなる。

この点を間違うとOff-by-one errorになる。

Numpy v0.2 > 符号に関する失敗

test_get_unique_rows_171225.py
import numpy as np

# on Python 3.5.2


def get_unique_rows(vs):
    unqs = np.unique(vs, axis=0)
    idxs = []
    for alist in vs:
        wrk = np.where(unqs == alist)
        idxs += [wrk[0][0]]
    return np.array(unqs), np.array(idxs)

vs = [
    [3, 1, 4],
    [1, 5, 9],
    [1, 5, 9],
    [-1, 5, -9],
    [2, 6, 5],
    ]
vs = np.array(vs)
res, idx = get_unique_rows(vs)
print('---original')
print(vs)
print('---unique')
print(res)
print('---index')
print(idx)
run
$ python3 test_get_unique_rows_171225.py 
---original
[[ 3  1  4]
 [ 1  5  9]
 [ 1  5  9]
 [-1  5 -9]
 [ 2  6  5]]
---unique
[[ 1  5  9]
 [ 2  6  5]
 [ 3  1  4]
 [-1  5 -9]]
---index
[2 0 0 0 1]

indexに関して、マイナス符号がついているものをプラスのセットとしてwhereで取るようだ。
上記は[2 0 0 3 1]でないとおかしい。

Numpy v0.3

test_get_unique_rows_171225.py
import numpy as np
import sys

# on Python 3.5.2


def get_unique_rows(vs):
    unqs = np.unique(vs, axis=0)
    idxs = []
    for alist in vs:
        wrk, _ = np.where(unqs == alist)
        loc = -1
        for idx in wrk:
            if (unqs[idx] == alist).all():
                loc = idx
                break
        idxs += [loc]
    return np.array(unqs), np.array(idxs)

vs = [
    [3, 1, 4],
    [1, 5, 9],
    [1, 5, 9],
    [-1, 5, -9],
    [2, 6, 5],
    ]
vs = np.array(vs)
res, idx = get_unique_rows(vs)
print('---original')
print(vs)
print('---unique')
print(res)
print('---index')
print(idx)

run
$ python3 test_get_unique_rows_171225.py 
---original
[[ 3  1  4]
 [ 1  5  9]
 [ 1  5  9]
 [-1  5 -9]
 [ 2  6  5]]
---unique
[[ 1  5  9]
 [ 2  6  5]
 [ 3  1  4]
 [-1  5 -9]]
---index
[2 0 0 3 1]

希望通りの結果になった。