numpyの基本テクニック

numpyとはpythonにおいて数値計算を行うことができるライブラリで、多次元配列や行列を簡単に計算出来るため、機械学習では必須テクニックとなります。
今回は、そのnumpyの基本的なテクニックをメモしておきます。

#numpyの基本テクニック
##import
```py
import numpy as np
```

##基本的な配列の生成
配列の生成には、np.array()メソッドを使う。

- 1*3の配列

```py
np.array([1,2,3])
```
![スクリーンショット 2019-02-04 21.32.56.png](https://qiita-image-store.s3.amazonaws.com/0/346585/bde9d601-aa32-17c5-7d44-9ec19babdef4.png)


- 3*3の配列

```py
np.array([[1,2,3],[4,5,6],[7,8,9]])
```
![スクリーンショット 2019-02-04 21.33.23.png](https://qiita-image-store.s3.amazonaws.com/0/346585/d73c939f-eb4c-c3e2-a902-21a6155cc203.png)


##形状の確認
配列の形状を確認するには、shape属性を参照すると形状が確認できます。

- ３列の形状

```py
array = np.array([1,2,3])
array.shape
```
![スクリーンショット 2019-02-04 21.33.53.png](https://qiita-image-store.s3.amazonaws.com/0/346585/f77da843-9ff5-bebd-d509-a2748a0d297e.png)

- 3*2の配列

```py
array = np.array([[1,2],[3,4],[5,6]])
array.shape
```
![スクリーンショット 2019-02-04 21.35.07.png](https://qiita-image-store.s3.amazonaws.com/0/346585/179f4038-5131-2b11-592a-28dedef8224c.png)

- 配列が何行なのか参照

```py
array.shape[0]
```
![スクリーンショット 2019-02-04 21.36.40.png](https://qiita-image-store.s3.amazonaws.com/0/346585/e2053f94-8137-fa52-9437-4571b2293b43.png)

- 配列が何列なのか参照

```py
array.shape[1]
```
![スクリーンショット 2019-02-04 21.37.33.png](https://qiita-image-store.s3.amazonaws.com/0/346585/0312c15c-f851-715a-aa59-74cf60c60182.png)

##形状の変換
形状の変換にはrehapeメソッドを使います。
特に列ベクトル（列数１の行列）への変換、多次元配列の１次元への変換は必須テクニックとなります。

array = np.array([[1,2],[3,4],[5,6]])

- 2*3列に変換

```py
array.reshape(2,3)
```
![スクリーンショット 2019-02-04 21.40.41.png](https://qiita-image-store.s3.amazonaws.com/0/346585/78b1204c-f648-bbc9-a882-e6f00802047c.png)

- X行１列に変換

```py
array.reshape(-1,1)
```
![スクリーンショット 2019-02-04 21.44.13.png](https://qiita-image-store.s3.amazonaws.com/0/346585/b16ab803-8563-ef4d-1a65-09195e294cd2.png)

- 配列を１次元に変換

```py
array.ravel()
```
![スクリーンショット 2019-02-04 21.46.39.png](https://qiita-image-store.s3.amazonaws.com/0/346585/12431b04-22ac-e049-4702-fde4287559db.png)

##選択と抽出
配列の一部を選択・抽出したい場面は多くあります。
特に:（スライス）のテクニック忘れないように。

array = np.array([[1,2],[3,4],[5,6]])

- １一行目を抽出

```py
array[0]
```
![スクリーンショット 2019-02-04 21.49.01.png](https://qiita-image-store.s3.amazonaws.com/0/346585/655a7ea1-3369-cff8-cbec-41c048b7aff4.png)

- ２行目以降を抽出

```py
array[1:]
```
![スクリーンショット 2019-02-04 21.52.23.png](https://qiita-image-store.s3.amazonaws.com/0/346585/e7d2d3ad-4036-ef68-7fc4-fd50c9ced08b.png)

- ２行目までを抽出

```py
array[:2] 
```
![スクリーンショット 2019-02-04 21.53.07.png](https://qiita-image-store.s3.amazonaws.com/0/346585/c03b5dd1-7916-59ce-3bfc-aea757ac7b9e.png)

- 1行目の２列目を抽出

```py
array[0, 1] #array[0][1]
```
![スクリーンショット 2019-02-04 21.54.04.png](https://qiita-image-store.s3.amazonaws.com/0/346585/daa605e8-7a75-541e-a4db-ab66b3fecae3.png)

- ２列目のみ抽出

```py
array[:, 1]
```
![スクリーンショット 2019-02-04 21.55.20.png](https://qiita-image-store.s3.amazonaws.com/0/346585/9689225a-5e20-37f4-5924-3c6c00c54fe6.png)

##条件による選択
配列から、ある条件を満たす要素のみを取り出したい時や、ある条件を満たす要素を別の値に置き換えたい場合は、whereメソッドなどを使う。

array = np.array([[1,2],[3,4],[5,6]])

- 2を境にture,falseで返す

```py
array > 2
```
![スクリーンショット 2019-02-04 21.58.14.png](https://qiita-image-store.s3.amazonaws.com/0/346585/47c322b8-43ae-8404-7543-b30c7f7dce6d.png)

- 2以上の数値を返す

```py
array[array > 2]
```
![スクリーンショット 2019-02-04 21.59.20.png](https://qiita-image-store.s3.amazonaws.com/0/346585/95a0dc40-3cd7-c53c-7846-786f3d80f991.png)

ある条件を満たす要素を置き換える時は、whereメソッドを使う。引数の条件は（条件、　置き換える値、　条件を満たさない要素の値）。

- yが０.５以上で１、０.５以下で０を返す

```py
x = np.arange(20).reshape(-1,1)
y = np.random.rand(20)
y = np.where(y < 0.5, 0, 1).reshape(-1,1)
```
![スクリーンショット 2019-02-04 22.00.58.png](https://qiita-image-store.s3.amazonaws.com/0/346585/f173eb15-855b-97e5-ff53-36802448388a.png)

- xのうちyが１になった値のみを抽出

```py
x = np.arange(20).reshape(-1,1)
y = np.random.rand(20)
y = np.where(y < 0.5, 0, 1).reshape(-1,1)
```
![スクリーンショット 2019-02-04 22.02.18.png](https://qiita-image-store.s3.amazonaws.com/0/346585/4c489660-e6c9-d95a-3b1c-fc8b9a8230c6.png)

##配列の結合
vstackは縦方向、hstackは横方向にそれぞれ配列を結合します。

- 縦方向に結合

```py
array_1 = np.array([[1,2],[3,4],[5,6]])
array_2 = np.array([[7,8],[9,10],[11,12]])
np.vstack([array_1,array_2])
```
![スクリーンショット 2019-02-04 22.05.12.png](https://qiita-image-store.s3.amazonaws.com/0/346585/085f87b3-484e-c4c0-0eb3-4b7b1fe0ad17.png)

- 横方向に結合

```py
array_1 = np.array([[1,2],[3,4],[5,6]])
array_2 = np.array([[7,8],[9,10],[11,12]])
np.hstack([array_1,array_2])
```
![スクリーンショット 2019-02-04 22.06.35.png](https://qiita-image-store.s3.amazonaws.com/0/346585/0cc44b25-a63a-675e-0f9b-bffe1ed70ff5.png)

なお異なった形状の配列は結合することはできません。

```py
array_1 = np.array([[1,2],[3,4],[5,6]])
array_2 = np.array([[7,8,9,10,11,12]])
print(array_1.shape)
print(array_2.shape)
```
![スクリーンショット 2019-02-04 22.07.53.png](https://qiita-image-store.s3.amazonaws.com/0/346585/4a43742d-2d6a-f5af-ede9-940acbf0dfe0.png)

##便利な配列生成方法

- 範囲を指定して配列を生成

```py
np.arange(0, 10)
```
![スクリーンショット 2019-02-04 22.09.09.png](https://qiita-image-store.s3.amazonaws.com/0/346585/28c16c44-eb09-368f-3017-c34f540b130c.png)

- 全ての配列が０の配列を生成。同様に1の配列はonesを使う。

```py
np.zeros([3, 3])
```
![スクリーンショット 2019-02-04 22.10.28.png](https://qiita-image-store.s3.amazonaws.com/0/346585/a5129fb1-e5a1-015f-cac6-8024546cf6db.png)

- 指定した配列と同じ形状の０行列を生成。同様にoneslikeもある。

```py
array = np.array([[1,2],[3,4],[5,6]])
np.zeros_like(array)
```
![スクリーンショット 2019-02-04 22.11.39.png](https://qiita-image-store.s3.amazonaws.com/0/346585/63ba672a-9d85-7134-6cb8-94c3fa62ef2f.png)

- 指定した範囲を等間隔で分割した配列を生成

```py
np.linspace(0, 2, 5)
```
![スクリーンショット 2019-02-04 22.12.24.png](https://qiita-image-store.s3.amazonaws.com/0/346585/9ba3c55d-8db4-f8c3-b940-ca60e0cd1836.png)

##乱数の生成
乱数の生成には、主にrandn,rand,randintのいずれかを使います。
乱数を固定するには、np.random.seed()を指定します

- 標準正規分布（平均０、分散１）に従って乱数を生成

```py
 np.random.randn(10)
```
![スクリーンショット 2019-02-04 22.16.37.png](https://qiita-image-store.s3.amazonaws.com/0/346585/73c302c7-f832-efed-26af-e62578510f2e.png)

- ０から１までの範囲で乱数を生成

```py
np.random.rand(10)
```
![スクリーンショット 2019-02-04 22.17.44.png](https://qiita-image-store.s3.amazonaws.com/0/346585/fcb02d9c-a984-0e05-8bb9-e6085f99337d.png)

- 指定した範囲の整数をランダムに抽出

```py
np.random.randint(0, 100, 10) #０から１００を１０個生成する
```
![スクリーンショット 2019-02-04 22.19.09.png](https://qiita-image-store.s3.amazonaws.com/0/346585/fce7be8c-6f8d-0df2-1186-c13b098d12d6.png)

##四則演算
もちろん四則演算も可能です。

array_1 = np.array([[1,2],[3,4],[5,6]])
array_2 = np.array([[7,8],[9,10],[11,12]])

- 和

```py
array_1 + array_2
```
![スクリーンショット 2019-02-04 22.21.43.png](https://qiita-image-store.s3.amazonaws.com/0/346585/feadf5bc-2510-c646-c10a-48779643dd21.png)

- 差

```py
array_1 - array_2
```
![スクリーンショット 2019-02-04 22.22.19.png](https://qiita-image-store.s3.amazonaws.com/0/346585/82f9a50b-1117-67db-9ed9-3b17618065ef.png)

- 商

```py
array_1 * array_2
```
![スクリーンショット 2019-02-04 22.23.05.png](https://qiita-image-store.s3.amazonaws.com/0/346585/587ec0a7-f977-ccfc-501e-e79a29605075.png)

- 積

```py
array_1 / array_2
```
![スクリーンショット 2019-02-04 22.23.50.png](https://qiita-image-store.s3.amazonaws.com/0/346585/c6505a79-68e0-8549-cb90-dd1c2ad5e9e2.png)

- 累乗

```py
array_1 ** 2 #もしくはnp.sqrt(array_1)
```
![スクリーンショット 2019-02-04 22.24.43.png](https://qiita-image-store.s3.amazonaws.com/0/346585/f14a6d6c-6aa7-83df-386b-68add7d6d919.png)

- 指数関数

```py
np.exp(array)
```
![スクリーンショット 2019-02-04 22.25.37.png](https://qiita-image-store.s3.amazonaws.com/0/346585/4b1f1f12-d394-9a4b-afd1-8327254d27f8.png)

- 対数関数

```py
np.log1p(array)
```
![スクリーンショット 2019-02-04 22.26.17.png](https://qiita-image-store.s3.amazonaws.com/0/346585/7f495afb-463f-49fe-c9f0-143a9b1aefbf.png)

##各種統計量

array = np.random.randint(0, 100, 20)

- 合計、平均、分散、標準偏差、最大値、最小値

```py
np.sum(array)
np.mean(array)
np.var(array)
np.std(array)
np.max(array)
np.argmax(array) #最大値のインデックス
np.min(array)
np.argmin(array) #最小値のインデックス
```
##その他便利なやつ
```py
array.dtype　#データの型を調べる
array = np.random.randint(0, 100, 20, dtype="int32") #データの型を指定して配列を生成する（int32）
np.round(array, 2) #小数点以下２桁に揃える
```