見出し画像

GCI (東京大学オンライン講義)第3回 練習問題 2 【解説あり】

GCI (東京大学オンライン講義)第3回 練習問題 1 【解説あり】の続きです。

問1 インデキシングの基礎
あなたが作成した任意の配列に対して,前から一番目と後ろから一番目の値を取得して表示してください。

a = np.array(make_list()) #using make_list function which I made before 

print("前から一番目の値:",a[0])
print("後ろから一番目の値:",a[-1])

ほとんどのプログラミング言語は0からスタートするので、一番目は0です。後ろから数えるときは、-1からです。

実行結果
Enter a number of elements: 5
Enter a number: 1
Enter a number: 2
Enter a number: 3
Enter a number: 4
Enter a number: 5
[1, 2, 3, 4, 5]
前から一番目の値: 1
後ろから一番目の値: 5

問2 ブールインデックス参照
(1) 整数値を値にもつNumpyの1次元配列を引数として,奇数または4で割って2余るような配列の値を列挙する関数を実装してください。

def make_bool_ids(a):
   idx = np.bitwise_or(a%4==2,a%2==1) # % is mod, this means remainder
   b = a[idx]
   return b # b is `np.ndarray`
make_bool_ids(np.array(make_list()))

idxはbool値を返しますが、a[idx]をbに代入することによって、ndarrayとしてtrueに対応する部分だけ取り出してくれます。bitwise_orはユニバーサル関数。ユニバーサル関数は以下で確認できます。

実行結果
Enter a number of elements: 9
Enter a number: 1
Enter a number: 2
Enter a number: 3
Enter a number: 4
Enter a number: 5
Enter a number: 6
Enter a number: 7
Enter a number: 8
Enter a number: 9
[1, 2, 3, 4, 5, 6, 7, 8, 9]
array([1, 2, 3, 5, 6, 7, 9])

(2) 正の整数を引数として,その数より小さい正の平方数の個数をブールインデックス参照を用いて求める関数を実装してください(ヒント:十分な数の正の平方数を小さい順に列挙し,その中で引数より小さいものを数える)。

def count_square(n): #def func 
    a = np.square(np.arange(1,n)) #make ndarray n**2 (from 1 to n)
    idx = (a<=n) #when a<=n, into idx 
    answer = a[idx] 
    return answer

count_square(64)

まず、np.square&arangeを用いて十分な長さの十分な数の正の平方数のndarrayを生成します。次に、ブールインデックス参照を用いてnより小さい要素を返せばよい。

実行結果
array([ 1, 4, 9, 16, 25, 36, 49, 64], dtype=int32)

問1 (1) 5人の生徒の4回分のテストの点数の結果を100点満点で2次元配列に格納してください。このとき,axis 0を生徒でaxis 1をテストの各回だとします。また,値は任意であるとします。

def array_conv(a, x, y):
   a = np.array(a) #convert list to ndarray 
   a = a.reshape(x, y) #reshape
   return a

後々楽になると思ったので、先にnp.reshapeを用いてarrayを変換する関数を定義しました。ここでのaはlist型です。前回定義したmake_list()を用いるためです。

array_conv(make_list(),5,4) #using function 

5人が4回のテストなので必要な要素は20個です。axis 0 = 生徒、asix 1 = テストなので、x=5, y=4で入力します。点数はテキトーです(笑)

実行結果
Enter a number of elements: 20
[90, 95, 80, 75, 60, 44, 60, 30, 100, 100, 80, 90, 55, 66, 77, 88, 1, 2, 3, 4]

array([[ 90, 95, 80, 75],
[ 60, 44, 60, 30],
[100, 100, 80, 90],
[ 55, 66, 77, 88],
[ 1, 2, 3, 4]])

(2) それぞれの生徒の4回分のテスト結果の最高点・最低点・平均・分散をそれぞれ計算してください。その結果をaxis 0が生徒, axis 1が集約結果(最高点・最低点・平均・分散)となる2次元配列にしてください。

#using a same as (1) 
print(np.stack([np.max(a, axis=1), np.min(a, axis=1), np.mean(a, axis=1), np.var(a, axis=1)], 1)) 
実行結果
[[ 95. 75. 85. 62.5 ]
[ 60. 30. 48.5 156.75]
[100. 80. 92.5 68.75]
[ 88. 55. 71.5 151.25]
[ 4. 1. 2.5 1.25]]

np.stackを用いることで、axis 1に対して結合することができます。
使用例)np.stack([array1,array2,...], axis number)
ちなみに、最大値はnp.max()、最小値はnp.min()、平均値はnp.mean()、分散はnp.var()で求めることができます。

(3) 各テストの点数について,その点数がその生徒の平均点から絶対値で何点差かを求めたshape=(5, 4)の2次元配列を計算してください。

b = np.mean(a, axis=1, keepdims=True) #use np.mean
print(np.abs(a-b))  #use np.abs 

bで求めたnp.mean(平均値)の形は(5, 1) なので、ブロードキャストが起こります。 keepdimsをTrueにすると、axisの意味を変えずに結果を返します。
あとは、絶対値(np.abs)を用いてprintすればいいのみです。

実行結果
[[ 5. 10. 5. 10. ]
[11.5 4.5 11.5 18.5]
[ 7.5 7.5 12.5 2.5]
[16.5 5.5 5.5 16.5]
[ 1. 0. 1. 0. ]]

~最後に~

最後まで読んでいただき、ありがとうございます。質問や間違えているところがあればコメントで教えていただければ嬉しいです。アドバイスなどもしていただければありがたいです。これからも投稿していこうと思っているのでよろしくお願いします!

↓練習問題 1 はこちらです、是非見てください!

この記事が気に入ったらサポートをしてみませんか?