pythonによるデータ分析入門を写経していく(numpyの使い方)
- この本
numpyの配列の生成
pythonの配列を
np.array()
に渡して上げるIn [337]: data1 = [1,2,3,4,5] In [338]: a = np.array(data1) In [339]: a Out[339]: array([1, 2, 3, 4, 5])
配列の計算
Rと同じ感じ
In [332]: data = array([[1,2,3],[4,5,6]]) In [333]: data Out[333]: array([[1, 2, 3], [4, 5, 6]]) In [334]: data * 10 Out[334]: array([[10, 20, 30], [40, 50, 60]])
配列の構造とデータ型の取得
array.shape
で構造、array.dtype
で型を取得できるIn [335]: data.shape Out[335]: (2, 3) In [336]: data.dtype Out[336]: dtype('int64')
配列の初期化
numpy.zeros()
でゼロ埋めの初期化- 単一の数字で渡すと、その数分だけ生成される
タプルで渡すと、多次元配列が可能
In [349]: np.zeros(10) Out[349]: array([ 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.]) In [350]: np.zeros((2,3)) Out[350]: array([[ 0., 0., 0.], [ 0., 0., 0.]])
numpy.ones()で1埋め
In [352]: np.ones((2,3)) Out[352]: array([[ 1., 1., 1.], [ 1., 1., 1.]])
numpy.empty()で何かしらの数字埋め
In [353]: np.empty((2,3)) Out[353]: array([[ -2.00000000e+000, 1.49457443e-154, 2.13643686e-314], [ 2.13643937e-314, 2.13643940e-314, 4.21536564e-309]])
numpy.arange()で等差数列
In [354]: np.arange(10) Out[354]: array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9]) In [355]: a = np.array([[1,2,3], [2,3,4]])
np.zeros_like()
である配列と同じ行列のフォーマットで0埋めした別の配列を生成するIn [356]: np.zeros_like(a) Out[356]: array([[0, 0, 0], [0, 0, 0]])
np.identity(n)
でN×Nの行列を生成する(正方形となる行列)In [357]: np.identity(3) Out[357]: array([[ 1., 0., 0.], [ 0., 1., 0.], [ 0., 0., 1.]])
型変換
astype()
でキャストして型変換することが可能In [358]: a Out[358]: array([[1, 2, 3], [2, 3, 4]]) In [359]: a.dtype Out[359]: dtype('int64') In [366]: a.astype(unicode_) Out[366]: array([['1', '2', '3'], ['2', '3', '4']], dtype='<U24')
スライシング
In [369]: arry = np.arange(20)
In [370]: arry
Out[370]:
array([ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16,
17, 18, 19])
ndarrayのデータアクセス方法
arry[]
Rと同じ感じ
In [371]: arry[4] Out[371]: 4 In [372]: arry[4:10] Out[372]: array([4, 5, 6, 7, 8, 9])
ndarrayから一部を切り出したものに値を代入することができる
//4~10を100に代入する In [373]: arry[4:10] = 100 In [374]: arry Out[374]: array([ 0, 1, 2, 3, 100, 100, 100, 100, 100, 100, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19])
ndarrayからスライスしたものの値を変更すると、スライス元のndarrayも変更される
コピーでなく、参照なので、オリジナルが書き変わってしまうので注意
In [375]: slice = arry[1:10] In [376]: slice Out[376]: array([ 1, 2, 3, 100, 100, 100, 100, 100, 100]) In [377]: slice[0] = 10000 In [378]: arry Out[378]: array([ 0, 10000, 2, 3, 100, 100, 100, 100, 100, 100, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19])
boolインデックス参照
参照元・参照先の要素数が一緒であれば、異なる配列のBool値を渡して、値を取り出すことができる
In [385]: names = np.array(['A','B','C','A','B','D','E']) In [381]: data = np.random.randn(7,4) In [382]: data Out[382]: array([[-0.4017517 , 0.1419749 , 2.6240324 , -0.44037342], [-0.18664907, 0.51251524, -0.30868358, -1.11172428], [-1.00609678, -0.64364957, 1.57684002, -2.52900976], [-0.22742879, -0.94647345, 1.00702104, -0.32474363], [ 1.67767647, 0.08669149, 0.99823391, -0.45566197], [ 1.19013211, 0.58920002, 0.34461962, 1.49732534], [ 1.05829828, 0.15391459, 0.71491311, -0.02964348]]) //この配列を別の配列に渡して、データを取り出すことできる In [386]: names == 'A' Out[386]: array([ True, False, False, True, False, False, False], dtype=bool) //nameがAのものを取り出す In [387]: data[names == 'A'] Out[387]: array([[-0.4017517 , 0.1419749 , 2.6240324 , -0.44037342], [-0.22742879, -0.94647345, 1.00702104, -0.32474363]]) //nameがA以外のものを取り出す In [388]: data[names != 'A'] Out[388]: array([[-0.18664907, 0.51251524, -0.30868358, -1.11172428], [-1.00609678, -0.64364957, 1.57684002, -2.52900976], [ 1.67767647, 0.08669149, 0.99823391, -0.45566197], [ 1.19013211, 0.58920002, 0.34461962, 1.49732534], [ 1.05829828, 0.15391459, 0.71491311, -0.02964348]])
複数条件を取り出すことも可能
- ただし、取り出したものの値を変更した場合、オリジナルの値が変更されてしまうので注意!
コピーではない
In [391]: mask = (names == 'A') | (names == 'D')
In [392]: mask Out[392]: array([ True, False, False, True, False, True, False], dtype=bool)
In [393]: data[mask] Out[393]: array([[-0.4017517 , 0.1419749 , 2.6240324 , -0.44037342], [-0.22742879, -0.94647345, 1.00702104, -0.32474363], [ 1.19013211, 0.58920002, 0.34461962, 1.49732534]])
特定条件による値の取り出し
特定の値より小さいかどうかを返す
In [395]: [data < 0] Out[395]: [array([[ True, False, False, True], [ True, False, True, True], [ True, True, False, True], [ True, True, False, True], [False, False, False, True], [False, False, False, False], [False, False, False, True]], dtype=bool)] In [394]: data[data < 0] Out[394]: array([-0.4017517 , -0.44037342, -0.18664907, -0.30868358, -1.11172428, -1.00609678, -0.64364957, -2.52900976, -0.22742879, -0.94647345, -0.32474363, -0.45566197, -0.02964348]) In [396]: data[data < 0] = 0 In [397]: data Out[397]: array([[ 0. , 0.1419749 , 2.6240324 , 0. ], [ 0. , 0.51251524, 0. , 0. ], [ 0. , 0. , 1.57684002, 0. ], [ 0. , 0. , 1.00702104, 0. ], [ 1.67767647, 0.08669149, 0.99823391, 0. ], [ 1.19013211, 0.58920002, 0.34461962, 1.49732534], [ 1.05829828, 0.15391459, 0.71491311, 0. ]])
ファンシーインデックス
特定の順序で行を抽出するには、その順序を配列で渡せばよい
In [404]: data Out[404]: array([[ 0., 0., 0., 0.], [ 1., 1., 1., 1.], [ 2., 2., 2., 2.], [ 3., 3., 3., 3.], [ 4., 4., 4., 4.], [ 5., 5., 5., 5.], [ 6., 6., 6., 6.], [ 7., 7., 7., 7.]]) In [405]: data[1] Out[405]: array([ 1., 1., 1., 1.]) //上と同じようなことを配列で渡せばよい In [407]: data[[2,1,3]] Out[407]: array([[ 2., 2., 2., 2.], [ 1., 1., 1., 1.], [ 3., 3., 3., 3.]])
行列の入れ替え
data.T
で行列変換これもコピーではなく、ビューを返すので、値の書き換えを実行してしまうとオリジナルが変更されるので注意S
In [408]: data Out[408]: array([[ 0., 0., 0., 0.], [ 1., 1., 1., 1.], [ 2., 2., 2., 2.], [ 3., 3., 3., 3.], [ 4., 4., 4., 4.], [ 5., 5., 5., 5.], [ 6., 6., 6., 6.], [ 7., 7., 7., 7.]]) In [409]: data.T Out[409]: array([[ 0., 1., 2., 3., 4., 5., 6., 7.], [ 0., 1., 2., 3., 4., 5., 6., 7.], [ 0., 1., 2., 3., 4., 5., 6., 7.], [ 0., 1., 2., 3., 4., 5., 6., 7.]])
- 内積を求める時に便利
In [410]: np.dot(data.T,data)
Out[410]:
array([[ 140., 140., 140., 140.],
[ 140., 140., 140., 140.],
[ 140., 140., 140., 140.],
[ 140., 140., 140., 140.]])
高次元の配列の場合もtransposeメソッドで入れ替え可能
In [411]: data = np.arange(16).reshape((2,2,4)) In [412]: data Out[412]: array([[[ 0, 1, 2, 3], [ 4, 5, 6, 7]], [[ 8, 9, 10, 11], [12, 13, 14, 15]]]) In [413]: data.tra data.trace data.transpose In [413]: data.transpose((1,0,2)) Out[413]: array([[[ 0, 1, 2, 3], [ 8, 9, 10, 11]], [[ 4, 5, 6, 7], [12, 13, 14, 15]]])
ラムダ
単項func
In [417]: arry Out[417]: array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9]) In [418]: result = np.sq np.sqrt np.square np.squeeze In [418]: result = np.sqrt(arry) In [419]: resu result result_type results In [419]: result Out[419]: array([ 0. , 1. , 1.41421356, 1.73205081, 2. , 2.23606798, 2.44948974, 2.64575131, 2.82842712, 3. ])
二項func
In [421]: x = np.arange(10) In [422]: y = np.arange(10) *10 In [423]: x Out[423]: array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9]) In [424]: y Out[424]: array([ 0, 10, 20, 30, 40, 50, 60, 70, 80, 90]) In [426]: np.add(x,y) Out[426]: array([ 0, 11, 22, 33, 44, 55, 66, 77, 88, 99])
特定の条件に合致するものの個数を調べる
True=1/False=0として計算されるので、条件でTFの列を返して、それのsum()をとる
In [428]: x Out[428]: array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9]) In [429]: (x >5) Out[429]: array([False, False, False, False, False, False, True, True, True, True], dtype=bool) In [430]: (x >5).sum() Out[430]: 4
その他使いそうなもの
- 配列の重複をのぞいたものを返す numpy.unique
- ソート numpy.sort