今回は,配列の要素に対して「ある条件が成立する要素」のみを取り出す方法です.
まずいつものようにnumpyをインポートして,正規乱数の10次元ベクトルを生成します.
import numpy as np
x = np.random.randn(10)
今回はこんな値が入りました.
>>> x
array([ 1.0751345 , 0.27759562, 1.90829034, 0.56632339, -0.76284511,
-0.41408957, 1.88271676, 0.32405545, -0.56915433, -0.90072913])
さて,ここからが本題です.この値の中で正の値だけを取り出した配列を作りたい場合どうすればいいでしょうか?
C言語風に書くと,
y = []
for n in range(len(x)):
if x[n]>0:
y = np.append(y, x[n])
となり,結果は
>>> y
array([1.0751345 , 0.27759562, 1.90829034, 0.56632339, 1.88271676,
0.32405545])
となります.うーむ,確かに出来るんですがこれだとPythonらしさが全然ないでしょうね.
まず,x > 0を実行してみます.
>>> x>0
array([ True, True, True, True, False, False, True, True, False,
False])
x>0か否か(True またはFalse)がそのままnumpy配列として出力されます.これを配列のインデクスに直接入れるとTrueに対応する要素のみ出力されます.
>>> x[x>0]
array([1.0751345 , 0.27759562, 1.90829034, 0.56632339, 1.88271676,
0.32405545])
C言語風に実行した結果(y)と全く同じになりました.なんて簡単!これは機械学習において,識別結果が教師データと同じか否かをTrue /Falseで出力し,Trueの数をカウントして正しく識別した割合(精度)を計算する場合にそのまま使えます.
たとえば,xの10個の要素の値の中で,正の値の数をカウントするには,
>>> len(x[x>0])
6
となります.全体の割合は6割ですが,それはlen(x[x>0])/len(x)で求まります.
まとめ
ある条件が成立する要素のみ取り出すには,
x[条件式]
と記載する.
問題2-1.x = np.random.randint(0,8,10)で,0以上8未満の値を要素に持つ10次元の配列を作る.このとき,(1) 偶数の要素のみ取り出した配列 y を作成せよ.(2) 奇数の要素の数を出力せよ.
解答2-1
>>> x = np.random.randint(0,8,10)
>>> x
array([1, 2, 7, 2, 1, 0, 4, 3, 6, 0])
>>> y = x[x%2==0]
>>> y
array([2, 2, 0, 4, 6, 0]) #(1)の答え
>>> len(x[x%2==1])
4 #(2)の答え
x%2は,xの各要素を2で割ったときの余りを表します.したがって,偶数の場合は2で割ると余り0(x%2==0),奇数の場合は2で割ると余り1(x%2==1)となるわけです.
問題2-2. x1 = np.random.randint(0,2,10)とx2 = np.random.randint(0,2,10)を実行してx1, x2を作成する.x1とx2の要素が同じ値となった個数を求めよ
解答2-2
>>> x1 = np.random.randint(0,2,10)
>>> x2 = np.random.randint(0,2,10)
>>> x1
array([0, 0, 1, 0, 0, 1, 1, 0, 1, 1])
>>> x2
array([0, 0, 1, 1, 1, 0, 0, 1, 1, 1])
>>> x1[x1==x2]
array([0, 0, 1, 1, 1])
>>> len(x1[x1==x2]) # len(x2[x1==x2])でも同じ
5