Python | Numpy > list > xの値が指定範囲の(x,y)リストを返す > keep_flgs = np.logical_and(xns >= xmin, xns <= xmax) | keep_flgs = (xns >= xmin) & (xns <= xmax)

```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)
ADDA v.1.3b6
```

### 関連

- [Python | Numpy > list > xの値が閾値未満の(x,y)の値を取り除いたリストを返す | link: ValueError: not enough values to unpack | 教えていただいた事項: Numpy.numpy.greater_equal()を使ったコード](https://qiita.com/7of9/items/3a79f13d3af2237dd447)

### 内容

```py
xs = [0, 1, 2, 3, 4]
ys = [3, 1, 4, 1, 5]
```

- 上記のような(x,y)の組合せが与えられている
- xは昇順にソートされている
- xに対して指定範囲の(x,y)の組合せを得たい
    - 例: 2 <= x <= 3


@carnage さんに[教えていただいた](https://qiita.com/7of9/items/3a79f13d3af2237dd447/#comment-353786ed639b4035eff0)Numpyのgreater_equals()と関連して[numpy.logical_and()](https://docs.scipy.org/doc/numpy-1.13.0/reference/generated/numpy.logical_and.html#numpy.logical_and)という関数を見つけました。

>```.py
>>> x = np.arange(5)
>>> np.logical_and(x>1, x<4)
array([False, False,  True,  True, False], dtype=bool)
```

使ってみました。

### code v0.1

```test_remove_outside_180114.py
import numpy as np

xs = [0, 1, 2, 3, 4]
ys = [3, 1, 4, 1, 5]


def remove_lessThan(xs, ys, xmin):
    # Acknowledgement: @carnage
    # at https://qiita.com/7of9/items/3a79f13d3af2237dd447#comment-353786ed639b4035eff0
    ge_flags = np.greater_equal(xs, xmin)
    return np.array(xs)[ge_flags], np.array(ys)[ge_flags]


def remove_outsideOf(xs, ys, xmin, xmax):
    xns, yns = np.array(xs), np.array(ys)
    keep_flgs = np.logical_and(xns >= xmin, xns <= xmax)
    print(keep_flgs)
    return xns[keep_flgs], yns[keep_flgs]


print(xs, ys, end='\n\n')

# 1. less than
print('--remove for (x < 2)--')
wrkx, wrky = remove_lessThan(xs, ys, xmin=2)
print(wrkx, wrky)

# 2. in range
print('--remove outside of (x < 2), (x > 3)--')
wrkx, wrky = remove_outsideOf(xs, ys, xmin=2, xmax=3)
print(wrkx, wrky)

```

```txt:run
$ python3 test_remove_outside_180114.py 
[0, 1, 2, 3, 4] [3, 1, 4, 1, 5]

--remove for (x < 2)--
[2 3 4] [4 1 5]
--remove outside of (x < 2), (x > 3)--
[False False  True  True False]
[2 3] [4 1]
```

Logical functionsを使うことで、シンプルな実装にできるようになりました。


### 備考

- 関数名はremove_outsideOf()でなくget_inrangeOf()などにするのが良い?


### code v0.2

keep_flagsに関して@skotaro さんの[コメント](https://qiita.com/7of9/items/3a79f13d3af2237dd447/#comment-28314627dedaaefa6594)にて教えていただいたBoolean indexingを使ってみました。

関連: [Combining logic statements AND in numpy array](https://stackoverflow.com/questions/21996661/combining-logic-statements-and-in-numpy-array)

```test_remove_outside_180114.py
import numpy as np

xs = [0, 1, 2, 3, 4]
ys = [3, 1, 4, 1, 5]


def remove_lessThan(xs, ys, xmin):
    # Acknowledgement: @carnage
    # at https://qiita.com/7of9/items/3a79f13d3af2237dd447#comment-353786ed639b4035eff0
    ge_flags = np.greater_equal(xs, xmin)
    return np.array(xs)[ge_flags], np.array(ys)[ge_flags]


def remove_outsideOf(xs, ys, xmin, xmax):
    xns, yns = np.array(xs), np.array(ys)
    #keep_flgs = np.logical_and(xns >= xmin, xns <= xmax)
    keep_flgs = (xns >= xmin) & (xns <= xmax)
    print(keep_flgs)
    return xns[keep_flgs], yns[keep_flgs]


print(xs, ys, end='\n\n')

# 1. less than
print('--remove for (x < 2)--')
wrkx, wrky = remove_lessThan(xs, ys, xmin=2)
print(wrkx, wrky)

# 2. in range
print('--remove outside of (x < 2), (x > 3)--')
wrkx, wrky = remove_outsideOf(xs, ys, xmin=2, xmax=3)
print(wrkx, wrky)
```

```txt:run
$ python3 test_remove_outside_180114.py 
[0, 1, 2, 3, 4] [3, 1, 4, 1, 5]

--remove for (x < 2)--
[2 3 4] [4 1 5]
--remove outside of (x < 2), (x > 3)--
[False False  True  True False]
[2 3] [4 1]
```

さらにシンプルにできました。