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

```txt:動作環境
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 > unique(vs, 'rows')を使ってみた > [res, ~, idx] = unique(vs, 'rows')](https://qiita.com/7of9/items/9a43f4fb1a3b8d9b2b92)
- [MATLAB > [v,~,idx] = unique(v,'rows'); > tilde(~):プレースホルダ > Pythonでの下線(_)に相当するのだろう](https://qiita.com/7of9/items/8116a12880f41314e279)

### MATLAB

```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](https://stackoverflow.com/questions/432112/is-there-a-numpy-function-to-return-the-first-index-of-something-in-an-array)
> answered Jan 11 '09 at 3:12
Alex

```py
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)

```

```txt: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](https://qiita.com/7of9/items/9cf5e9c1e8751c23dbd5)になる。


## 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)
```

```txt: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)

```

```txt: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]
```

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