【100 numpy exercises】でnumpy力を鍛える！（１１〜２０問目）

こんにちは！

前回はnumpy力を鍛えるために1~10問やっていきました。

前回の記事はこちら

https://qiita.com/fav/items/356b885a6ea383801b32

それでは前回に引き続き[100 numpy exercises](https://github.com/rougier/numpy-100/)を使ってnumpyの学習をしていきたいと思います！

今回は11~20問をやっていきます。

###11. Create a 3x3 identity matrix (★☆☆)
#####11. 3×3の単位行列を作る

```ruby:100_numpy_exercises.ipynb(11)
Z = np.eye(3)
print(Z)
```

***np.eye***は単位行列を生成する関数です。今回は括弧内のパラメータに3を指定することによって*3×3*の単位行列を作りました他にも***np.identity***でも単位行列は作れたりします。***np.eye***との違いはほとんどありません。

実行結果は以下の通りです。

```ruby:100_numpy_exercises.ipynb(11)-output
[[1. 0. 0.]
 [0. 1. 0.]
 [0. 0. 1.]]
```

###12. Create a 3x3x3 array with random values (★☆☆)
#####12. ランダムな値で3×3×3の配列を作る

```ruby:100_numpy_exercises.ipynb(12)
Z = np.random.random((3,3,3))
print(Z)
```

***np.random.random***はサイズをタプルで渡すとそのタプルに応じた形で乱数が生成されます。今回は*3×3×3*の配列を作成したかったので、(3,3,3)というタプルを渡しました。

実行結果は以下の通りです。

```ruby:100_numpy_exercises.ipynb(12)-output
[[[0.97800262 0.91772958 0.75703288]
  [0.86126759 0.11191541 0.6370986 ]
  [0.8174457  0.49128777 0.47512889]]

 [[0.01935817 0.11916116 0.95121243]
  [0.50533707 0.72976053 0.46982338]
  [0.95131124 0.3853439  0.12364288]]

 [[0.84269566 0.5485603  0.35162625]
  [0.49270204 0.17011739 0.70630649]
  [0.51482216 0.62225406 0.14056554]]]
```



###13. Create a 10x10 array with random values and find the minimum and maximum values (★☆☆)
#####13. ランダムな値で10×10の配列を作り、最小値と最大値を求める

```ruby:100_numpy_exercises.ipynb(13)
Z = np.random.random((10,10))
Zmin, Zmax = Z.min(), Z.max()
print(Zmin, Zmax)
```

***np.random.random***でランダムな*10×10*の配列を生成します。あとは、***min***と***max***で配列の要素の最大値と最小値を求めることができます。

実行結果は以下の通りです。

```ruby:100_numpy_exercises.ipynb(13)-output
0.015921867396830436 0.9810696239332971
```



###14. Create a random vector of size 30 and find the mean value (★☆☆)
#####14. サイズ30のランダムなベクトルを作成し、平均値を求める

```ruby:100_numpy_exercises.ipynb(14)
Z = np.random.random(30)
m = Z.mean()
print(m)
```

先ほども出てきた***np.random.random***は、タプルではなく１つの数字を渡すとそのサイズの１次元配列をランダムに生成します。生成された配列は***mean***でその平均値を求めることができます。

```ruby:100_numpy_exercises.ipynb(14)-output
0.5541803870580289
```

###15. Create a 2d array with 1 on the border and 0 inside (★☆☆)
#####15. 境界線上に1、内側に0の2次元配列を作る

```ruby:100_numpy_exercises.ipynb(15)
Z = np.ones((10,10))
Z[1:-1,1:-1] = 0
print(Z)
```

***np.ones***は要素が1の配列を生成します。ここでは(10,10)というタプルを渡しているので、要素が全て1で構成されている*10×10*の配列を生成します。

あとは内側が全部0で周りを囲むように1が配置されてあればよいので、*z[1:-1,1:-1]*で最初と最後の**行**、最初と最後の**列**以外を指定してあげ、0に置き換えるだけです。

実行結果は以下の通りです。

```ruby:100_numpy_exercises.ipynb(15)-output
[[1. 1. 1. 1. 1. 1. 1. 1. 1. 1.]
 [1. 0. 0. 0. 0. 0. 0. 0. 0. 1.]
 [1. 0. 0. 0. 0. 0. 0. 0. 0. 1.]
 [1. 0. 0. 0. 0. 0. 0. 0. 0. 1.]
 [1. 0. 0. 0. 0. 0. 0. 0. 0. 1.]
 [1. 0. 0. 0. 0. 0. 0. 0. 0. 1.]
 [1. 0. 0. 0. 0. 0. 0. 0. 0. 1.]
 [1. 0. 0. 0. 0. 0. 0. 0. 0. 1.]
 [1. 0. 0. 0. 0. 0. 0. 0. 0. 1.]
 [1. 1. 1. 1. 1. 1. 1. 1. 1. 1.]]
```



###16. How to add a border (filled with 0's) around an existing array? (★☆☆)
#####16. 既存の配列の周りにボーダー（0で埋める）を追加するには？

```ruby:100_numpy_exercises.ipynb(16)
Z = np.ones((5,5))
Z = np.pad(Z, pad_width=1, mode='constant', constant_values=0)
print(Z)
```

***np.ones***で*5×5*の要素が全て1の配列を生成します。***np.pad***は指定した値を配列に埋め込むことができる関数です。

実行結果は以下の通りです。

```ruby:100_numpy_exercises.ipynb(16)-output
[[0. 0. 0. 0. 0. 0. 0.]
 [0. 1. 1. 1. 1. 1. 0.]
 [0. 1. 1. 1. 1. 1. 0.]
 [0. 1. 1. 1. 1. 1. 0.]
 [0. 1. 1. 1. 1. 1. 0.]
 [0. 1. 1. 1. 1. 1. 0.]
 [0. 0. 0. 0. 0. 0. 0.]]
```



###17. What is the result of the following expression? (★☆☆)
#####17. 次の式の結果は何ですか？

```ruby:100_numpy_exercises.ipynb(17)
0 * np.nan
np.nan == np.nan
np.inf > np.nan
np.nan - np.nan
np.nan in set([np.nan])
0.3 == 3 * 0.1
```

実行結果は以下の通りです。

```ruby:100_numpy_exercises.ipynb(17)-output
nan
False
False
nan
True
False
```



###18. Create a 5x5 matrix with values 1,2,3,4 just below the diagonal (★☆☆)
#####18. 対角線のすぐ下に値1,2,3,4を持つ5x5の行列を作成します。

```ruby:100_numpy_exercises.ipynb(18)
Z = np.diag(1+np.arange(4),k=-1)
print(Z)
```

***np.diag***は対角成分を生成する関数です。第一引数に一次元配列を指定し、第二引数のkでは開始位置を指定できます。これによって第一引数の配列の要素がすべて収まる正方行列が返されます。

実行結果は以下の通りです。

```ruby:100_numpy_exercises.ipynb(18)-output
[[0 0 0 0 0]
 [1 0 0 0 0]
 [0 2 0 0 0]
 [0 0 3 0 0]
 [0 0 0 4 0]]
```

対角線のすぐ下に1,2,3,4の順で並んでいる正方行列が確認できました。



###19. Create a 8x8 matrix and fill it with a checkerboard pattern (★☆☆)
#####19. 8x8のマトリクスを作成し、市松模様で埋める

```ruby:100_numpy_exercises.ipynb(19)
Z = np.zeros((8,8),dtype=int)
Z[1::2,::2] = 1
Z[::2,1::2] = 1
print(Z)
```
***np.zeros***で*8×8*の正方行列を生成する。ここで一松模様とは何かというとこんな感じです。

![市松模様](https://livedoor.blogimg.jp/haikeisozai/imgs/2/1/21a1419f.png)

これを元に指定した場所を1に置き換えてあげればいいです。

実行結果は以下の通りです。

```ruby:100_numpy_exercises.ipynb(19)-output
[[0 1 0 1 0 1 0 1]
 [1 0 1 0 1 0 1 0]
 [0 1 0 1 0 1 0 1]
 [1 0 1 0 1 0 1 0]
 [0 1 0 1 0 1 0 1]
 [1 0 1 0 1 0 1 0]
 [0 1 0 1 0 1 0 1]
 [1 0 1 0 1 0 1 0]]
```



###20. Consider a (6,7,8) shape array, what is the index (x,y,z) of the 100th element? (★☆☆)
#####20. (6,7,8)形状の配列を考えたとき、100番目の要素のインデックス(x,y,z)は何か。

```ruby:100_numpy_exercises.ipynb(20)
print(np.unravel_index(99,(6,7,8)))
```

多次元配列に対して位置を知りたい時は、***np.unravel_index***を使えば１行で取得することができるみたいです。第一引数に何番目かを入れ、第二引数に次元を表すタプルを入れてあげればできます。

実行結果は以下の通りです。

```ruby:100_numpy_exercises.ipynb(20)-output
(1, 5, 3)
```

今回は以上になります。
次回は21~30問をやっていきます。

次回の記事

https://qiita.com/fav/items/db888c806ed92b68ed61