前回はこちら
前回記事の続きです。今回は100 numpy execiseのQ16-Q20を解いていきます。
16. How to add a border (filled with 0’s) around an existing array?
(既存の配列の周りに0で境界線を追加しなさい)
Z = np.ones((5,5))
Z = np.pad(Z,pad_width=1,mode='constant',constant_values=0)
print(Z)
[[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.]]
Q15との違いは元あった配列の値を変更するのではなく、元あった配列の外側に数値を追加するという点です。
この場合は np.pad()
を使うと楽にすることが可能です。
今回の引数を少し説明すると、pad_width=1
というのが境界線の太さです。mode='constant'
というのが標準モードを選択しています。他にもモードがたくさんあるので今回は説明しません。constant_values=0
というのは境界線の文字の指定ですね。ここで説明してもよくわからないと思うので、実際に値を変えて実行してみるとわかりやすいと思います。
17. What is the result of the following expression?
(これらを実行したらどうなりますか?)
一つずつ解説していきます
print(0 * np.nan)
nan
nan
というのは null
とほぼ同じと考えてもらっていいと思います。ただ None
とは異なります。
None
は存在自体がないことを表しています。numpy.nan
は数ではないものを表しています。このあたりの説明は難しいのでわかりやすい記事を貼っておきます。
【python】0,None,numpy.nanの比較 – Qiita
感覚的に理解してほしいのですが、何に nan
をかけても結果は nan
になります。
print(np.nan == np.nan)
False
これは予想と違ったかもしれません。一見左辺と右辺は同じに見えますが、先程も説明したとおり numpy.nan
は数ではない(非数)なので比較はできないのです。
print(np.inf > np.nan)
False
np.inf
は無限大を表すものです。一見 inf
のほうが大きく感じますが、inf
も nan
も非数なので比較はできません。よってこの式は False
になります。
print(np.nan - np.nan)
nan
nan
から nan
を引いても 0
にはなりません。これも今までと同様に nan
が非数だからです。非数は演算をすることができないのです。
print(np.nan in set([np.nan]))
True
nan
は非数ですが存在自体はあります。よって set
の要素として nan
を持っているのでこれは True
になります。
print(0.3 == 3 * 0.1)
False
これはかなりややこしい話なのでここではきっちりと説明できませんが、Python の float
型は C 言語の double
型を使って実装されていることが理由です。Python の浮動小数点値の精度は 53 ビットなので、ややこしい理由があります。詳しく知りたい人はググってください。これはコンピューターの仕組みなどに関わってくることなので一旦飛ばします。
18. Create a 5×5 matrix with values 1,2,3,4 just below the diagonal
対角線のすぐ下に1,2,3,4の値を持つ5×5行列を作れ
Z = np.diag(1+np.arange(4),k=-1)
print(Z)
np.diag()
に1次元の行列を渡すとそれを対角成分とする対角行列を返してくれます。k=-1
と指定しているのは下向きに一つずらすことを指定しています。(ずらすという表現であってるのかな?)
19. Create a 8×8 matrix and fill it with a checkerboard pattern
(チェッカーボード状の8×8行列を作れ)
Z = np.zeros((8,8),dtype=int)
#print(Z)
Z[1::2,::2] = 1
#print(Z)
Z[::2,1::2] = 2
print(Z)
[[0 2 0 2 0 2 0 2]
[1 0 1 0 1 0 1 0]
[0 2 0 2 0 2 0 2]
[1 0 1 0 1 0 1 0]
[0 2 0 2 0 2 0 2]
[1 0 1 0 1 0 1 0]
[0 2 0 2 0 2 0 2]
[1 0 1 0 1 0 1 0]]
要素が全て0の8×8行列を作成してから1と2を入れていっています。
1::2
は1を元にして1個間隔、::2
は0を元にして1個間隔で要素を指定できます。それを利用して行と列をうまくずらして1,2を入れています。
20. Consider a (6,7,8) shape array, what is the index (x,y,z) of the 100th element?
(shapeが(6,7,8)の配列において、100番目の要素の位置(x,y,z)を求めよ)
print(np.unravel_index(100,(6,7,8)))
(1, 5, 4)
100番目の要素が (x,y,z)=(1,5,4)
の位置にあることがわかりました。
unravel_index()
は配列を作ってから数える必要がありません。