NumPy(1) 備忘録

# NumPy
## 配列の初期化
NumPy行列計算をするためには、最初にNumPyの配列を生成(または初期化)する必要があります。 NumPy配列の実態は、`numpy.ndarray`というオブジェクトです。

```Python:
a = np.array([1, 2, 3, 4, 5])
print(a)
print(type(a))
```

> [1 2 3 4 5]
> \<class 'numpy.ndarray'\>

![np_01.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/476387/8c786b2c-6bfd-340a-4efb-a880e9ecd9ec.png)


NumPyで二次元の配列を作成するには、以下のように記述します。

```Python:
b = np.array([[1, 2, 3], [4, 5, 6]])
print(b)
```

> [[1 2 3]
>  [4 5 6]]

![np_02.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/476387/e335024b-1069-618b-89c5-f6b5f42fe367.png)

`np.zeros()`関数を用いて配列を0で初期化することができます。
`np.zeros()`にてタプルで複数の値を指定することで、指定した次元の配列を作成し0で初期化できます。

```Python:
print(np.zeros(10))
print(np.zeros((3, 2)))
```

> [0. 0. 0. 0. 0. 0. 0. 0. 0. 0.]
> [[0. 0.]
>  [0. 0.]
>  [0. 0.]]

![np_03.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/476387/7f5017a0-1437-0aa1-7b9a-7f304ea22c77.png)
![np_04.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/476387/9637396f-68e7-31ea-a197-a898dc201504.png)

`np.ones`関数を利用すると、1で初期化された配列を作成します。

```Python:
print(np.ones(10))
print(np.ones((3, 2)))
```

> [1. 1. 1. 1. 1. 1. 1. 1. 1. 1.]
> [[1. 1.]
>  [1. 1.]
>  [1. 1.]]

`np.arange`関数を使うと、連番の配列を作成できます。
`np.arange(開始,終了+1,加算値)`の書式で利用します。

```Python:
print(np.arange(5))
print(np.arange(2, 9))
print(np.arange(5, 8, 0.5))
```
> [0 1 2 3 4]
> [2 3 4 5 6 7 8]
> [5.  5.5 6.  6.5 7.  7.5]

![np_05.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/476387/38e56d11-82e4-64b4-211a-d8b32cc291e5.png)
![np_06.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/476387/65f29804-57c7-0c6b-30a1-461fbdd4e0ad.png)
![np_07.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/476387/868d1dc2-e730-5242-f71c-c314de14eedc.png)


## 行列計算

```Python:
a = np.arange(6)
b = a * 2
print(b)
```

> [ 0  2  4  6  8 10]

```Python:
x = np.arange(10)
y = 3 * x + 5
print(y)
```

> [ 5  8 11 14 17 20 23 26 29 32]

## NumPy配列の次元数を調べる
NumPy配列の`shape`プロパティを調べることで、次元数を確認できます。

```Python:
a = np.array([np.arange(1, 4), np.arange(4, 7)])
print(a.shape)

b = np.array([np.arange(1, 4), np.arange(4, 7), np.arange(7, 10)])
print(b.shape)
```
> (2, 3)
> (3, 3)

## 次元数の変換
`flatten`関数を使用することで、配列の次元数を手軽に変換できます。

```Python:
a = np.array([np.arange(1, 4), np.arange(4, 7)])
print("a=", a)
b = a.flatten()
print("b=", b)
```

> a= [[1 2 3]
>  [4 5 6]]
> b= [1 2 3 4 5 6]

`reshape`関数を使うことでも、配列の次元数を任意の形状に変換できます。

```Python:
a = np.array([np.arange(1, 4), np.arange(4, 7)])
print(a)
print(a.reshape(3, 2))
```

> [[1 2 3]
>  [4 5 6]]
> [[1 2]
>  [3 4]
>  [5 6]]

## NumPy配列の要素へのアクセス
Python標準の配列と同じように、要素にアクセスしたり、特定の範囲を取り出す(スライス)処理が可能です。

```Python:
v = np.array([np.arange(1, 4), np.arange(4, 7), np.arange(7, 10)])
print(v)
a = v[0]
b = v[1:]
c = v[:,0]
print("a=", a)
print("b=", b)
print("c=", c)
```

> [[1 2 3]
>  [4 5 6]
>  [7 8 9]]
> a= [1 2 3]
> b= [[4 5 6]
>  [7 8 9]]
> c= [1 4 7]

## 配列への次元の追加
`np.newaxis`を使用することで、次元に要素数1の新たな軸(axis)を追加できます。

```Python:
x = np.arange(15).reshape(3, 5)

print(x)

x[np.newaxis, :, :]
```

> [[ 0  1  2  3  4]
>  [ 5  6  7  8  9]
>  [10 11 12 13 14]]
> array([[[ 0,  1,  2,  3,  4],
>         [ 5,  6,  7,  8,  9],
>         [10, 11, 12, 13, 14]]])

```Python:
x = np.arange(15).reshape(3, 5)

print(x)

x[:, np.newaxis, :]
```

> [[ 0  1  2  3  4]
>  [ 5  6  7  8  9]
>  [10 11 12 13 14]]
> array([[[ 0,  1,  2,  3,  4]],
>        [[ 5,  6,  7,  8,  9]],
>      [[10, 11, 12, 13, 14]]])

## 線形の等間隔な配列の生成
`np.logspace`関数を用いることで、線形に等間隔な数列を生成できます。
`np.linspace`(開始,終了,要素数)の書式で使用します。

```Python:
a = np.linspace(1, 5, 9)
print(a)
```

> [1.  1.5 2.  2.5 3.  3.5 4.  4.5 5. ]

## ログスケールに均等な配列の生成
`np.logspace`関数を用いることで、ログスケールに増減する配列を生成できます。
`np.logspace(開始,終了,要素数,base=基数)`の書式で使用します。

```Python:
a = np.logspace(1, 5, 5, base=2)
print(a)
```

> [ 2.  4.  8. 16. 32.]

## リストやタプルからの配列の生成
`np.asarray`関数を用いることで、リストやタプルから配列を生成できます。

```Python:
a = [1, 2, 3, 4]
print(a)
print(type(a))
b = np.asarray(a)
print(b)
print(type(b))
```
> [1, 2, 3, 4]
> \<class 'list'\>
> [1 2 3 4]
> \<class 'numpy.ndarray'\>

```Python:
a = (1, 2, 3, 4)
print(a)
print(type(a))
b = np.array(a)
print(b)
print(type(b))
```

> (1, 2, 3, 4)
> \<class 'tuple'\>
> [1 2 3 4]
> \<class 'numpy.ndarray'\>

## 配列のソート
一次元配列の場合、`np.sort`関数を用いることで要素を昇順にソートできます。

```Python:
a = np.array([3,5,4,1,0,2])
print(a)
b = np.sort(a)
print(b)
```
> [3 5 4 1 0 2]
> [0 1 2 3 4 5]

`np.sort`関数には引数`reverse`が存在しないため、降順にしたい場合はスライス`[::-1]`を使います。

```Python:
a = np.array([3,5,4,1,0,2])
print(a)
b = np.sort(a)[::-1]
print(b)
```

> [3 5 4 1 0 2]
> [5 4 3 2 1 0]

多次元配列の場合、引数`axis`でソートする軸を選択します。
二次元配列を例にとると、`axis=0`で列を、`axis=1`で行をソートできます。

```Python:
a = np.array([[1,2,3],[2,3,1],[3,1,2]])
print(a)
b = np.sort(a, axis=0)
print(b)
c = np.sort(a, axis=1)
print(c)
```

> [[1 2 3]
>  [2 3 1]
>  [3 1 2]]
> [[1 1 1]
>  [2 2 2]
>  [3 3 3]]
> [[1 2 3]
>  [1 2 3]
>  [1 2 3]]

![np_08.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/476387/4d466c46-322f-7f80-66dc-4c0a3b3651d3.png)
![np_09.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/476387/3a36d8ed-d144-9b0f-f2f1-b6113f515ec7.png)

`np.argsort`関数は、値ではなく並び替えたインデックスの`ndarray`を返します。
引数`axis`などの考え方は、`np.sort`と同様です。

```Python:
a = np.array([[10,20,30],[20,30,10],[30,10,20]])
print(a)
b = np.argsort(a, axis=0)
print(b)
c = np.argsort(a, axis=1)
print(c)
```

> [[10 20 30]
>  [20 30 10]
>  [30 10 20]]
> [[0 2 1]
>  [1 0 2]
>  [2 1 0]]
> [[0 1 2]
>  [2 0 1]
>  [1 2 0]]

![np_10.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/476387/375b3bff-8552-a7dd-0435-1a096c76972c.png)
![np_11.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/476387/1de7e38d-7aec-9d63-c420-f4b66a2c5286.png)