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

こんにちは！

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

前回の記事はこちら

https://qiita.com/fav/items/1abed47a6b6e22f90179

それでは前回に引き続き100 numpy exercisesを使ってnumpyの学習をしていきたいと思います！

今回は21~30問をやっていきます。



###21. Create a checkerboard 8x8 matrix using the tile function (★☆☆)
#####21. tile関数を使って市松模様の8x8の行列を作る

```ruby:100_numpy_exercises.ipynb(21)
Z = np.tile( np.array([[0,1],[1,0]]), (4,4))
print(Z)
```

前回の記事で8x8のマトリクスを作成し、市松模様で埋めるという問題を解きましたが、今回はそれを**tile**関数というものでより簡単に作れてしまうというものです。**tile**関数は配列を任意のタイル状に繰り返し並べた新たな配列を生成できるものです。ここでは**np.array**で生成された二次元配列を*4×4*で並べています。

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

```ruby:100_numpy_exercises.ipynb(21)-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]]
```



###22. Normalize a 5x5 random matrix (★☆☆)
#####22. 5x5のランダム行列を正規化する

```ruby:100_numpy_exercises.ipynb(22)
Z = np.random.random((5,5))
Z = (Z - np.mean (Z)) / (np.std (Z))
print(Z)
```

***np.random.random***で*5×5*のランダム行列を生成する。生成した行列を正規化するには配列全体の要素の平均と標準偏差を算出して、正規化の式に当てはめてあげればいいです。

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

```ruby:100_numpy_exercises.ipynb(22)-output
[[-0.73910528 -0.48224877 -1.47811814  0.4865721   0.04907241]
 [-0.50927861 -0.11975964 -0.36532934 -0.43577001  1.51800836]
 [-0.94300421 -0.88632336  0.1297217   1.36665199  1.01731712]
 [ 1.65386281 -1.7164116   0.33569459 -1.00620105  1.38040459]
 [ 1.18378623 -0.5478284   1.56122167 -1.17090786 -0.28202728]]
```



###23. Create a custom dtype that describes a color as four unsigned bytes (RGBA) (★☆☆)
#####23. 色を4つの符号なしバイト（RGBA）で記述するカスタムdタイプを作成する

```ruby:100_numpy_exercises.ipynb(23)
color = np.dtype([("r", np.ubyte),
                  ("g", np.ubyte),
                  ("b", np.ubyte),
                  ("a", np.ubyte)])
```

この問題の目的は新しいデータ型を定義するということです。***np.dtype***で新しいデータ型を定義します。ここでは文字列部分がフィールド名称、***np.ubyte***はデータ型になります。



###24. Multiply a 5x3 matrix by a 3x2 matrix (real matrix product) (★☆☆)
#####24. 5x3の行列に3x2の行列を掛け合わせる（実数行列積）

```ruby:100_numpy_exercises.ipynb(24)
Z = np.ones((5,3)) @ np.ones((3,2))
print(Z)
```

内積の計算をします。行列の内積を求めたい時は、**@**が使えるので積極的に使っていくとスマートに計算できます。

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

```ruby:100_numpy_exercises.ipynb(24)-output
[[3. 3.]
 [3. 3.]
 [3. 3.]
 [3. 3.]
 [3. 3.]]
```



###25. Given a 1D array, negate all elements which are between 3 and 8, in place. (★☆☆)
#####25. 1次元の配列が与えられたとき、3から8までの要素をすべて否定してください

```ruby:100_numpy_exercises.ipynb(25)
Z = np.arange(11)
Z[(3 < Z) & (Z < 8)] *= -1
print(Z)
```

この問題は与えられた一次元配列に対して、条件に合う要素を反転させる。ここでは条件に合う範囲の要素に対して、**−1**を掛けています。

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

```ruby:100_numpy_exercises.ipynb(25)-output
[ 0  1  2  3 -4 -5 -6 -7  8  9 10]
```



###26. What is the output of the following script? (★☆☆)
#####26. 次のスクリプトの出力は何ですか？

```ruby:100_numpy_exercises.ipynb(26)
print(sum(range(5),-1))
from numpy import *
print(sum(range(5),-1))
```

第二引数はスタート地点を表しているようです。なので、-1+0・・・のように計算が続きます。

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

```ruby:100_numpy_exercises.ipynb(26)-output
9
10
```



###27. Consider an integer vector Z, which of these expressions are legal? (★☆☆)
#####27. 整数ベクトルZを考えると、次の表現のうちどれが正当か？

```ruby:100_numpy_exercises.ipynb(27)
Z = np.array([1,2,3,4,5])

Z**Z
2 << Z >> 2
Z <- Z
1j*Z
Z/1/1
Z<Z>Z
```

1つ目は各要素の二乗をします。
2つ目はシフト演算です。2を各要素分左にシフトしたあと、2ビットだけ右にシフトした結果です。
3つ目はおそらく、　z < -zが計算されてるのかなと思います。
4つ目は複素数の演算です。
5つ目は各要素に対して1で2回除算を行なっています。
6つ目はエラーが出ました。配列になっているため評価できない模様です。

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

```ruby:100_numpy_exercises.ipynb(27)-output
array([   1,    4,   27,  256, 3125])
array([ 1,  2,  4,  8, 16])
array([False, False, False, False, False])
array([0.+1.j, 0.+2.j, 0.+3.j, 0.+4.j, 0.+5.j])
array([1., 2., 3., 4., 5.])
ValueError                                Traceback (most recent call last)
<ipython-input-27-6d2bd9eb1fd1> in <module>
----> 1 Z<Z>Z

ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all()
```



###28. What are the result of the following expressions? (★☆☆)
#####28. 次の式の結果を教えてください

```ruby:100_numpy_exercises.ipynb(28)
np.array(0) / np.array(0)
np.array(0) // np.array(0)
np.array([np.nan]).astype(int).astype(float)
```

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

```ruby:100_numpy_exercises.ipynb(28)-output
<ipython-input-30-3585dcb7ab9b>:1: RuntimeWarning: invalid value encountered in true_divide
  np.array(0) / np.array(0)
nan
<ipython-input-31-4764261090d0>:1: RuntimeWarning: divide by zero encountered in floor_divide
  np.array(0) // np.array(0)
0
array([-9.22337204e+18])
```



###29. How to round away from zero a float array ? (★☆☆)
#####29. float配列をゼロから丸めるには？

```ruby:100_numpy_exercises.ipynb(29)
Z = np.random.uniform(-10,+10,10)
print(np.copysign(np.ceil(np.abs(Z)), Z))
```

***np.random.uniform***は任意の範囲の連続一様分布の乱数生成する関数です。第一引数には最小値、第二引数には最大値、第三引数にはサイズを指定しています。
***np.copysign***はある配列の符号を別の配列のものに置き換えることができます。第一引数の符号が第二引数の符号に置き換えられます。
***np.ceil***は少数の切り上げができ、***np.abs***は絶対値を取ることができます。

なのでこの問題では、***np.random.uniform**でランダムなfloat配列を生成して、絶対値をとった配列の小数点を切り上げ、もう一度元の符号をつけてあげるという流れです。

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

```ruby:100_numpy_exercises.ipynb(29)
[  1.   4.  10.  -1.  10.  -8.   5.   4. -10.  -4.]
```



###30. How to find common values between two arrays? (★☆☆)
#####30. 2つの配列の間の共通の値を見つけるには？

```ruby:100_numpy_exercises.ipynb(30)
Z1 = np.random.randint(0,10,10)
Z2 = np.random.randint(0,10,10)
print(np.intersect1d(Z1,Z2))
```

***np.intersect1d***は共通集合の抽出ができる関数です。

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

```ruby:100_numpy_exercises.ipynb(30)-output
[0 3 4 5 6 8]
```



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

次回の記事はこちら

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