初心者エンジニアの理論と実践メモ

本や授業のスライドをかみ砕いたメモ。機械学習メインで。

Numpy(Numerical Python)の基本

ndarrayの多次元配列オブジェクト

ndarray: N-dimensional arrayの略

ndarray 属性

ndarray.dtype
ndarray.shape

ndarray 生成

  • 書式
np.array(リスト、タプル、Python配列など)
np.arange(スカラー)
np.zeros(スカラー、タプル)
np.zeros_like(配列)
np.ones()
np.ones_like()

# 各要素の値を適当にして生成(この機能何に使うの??)
np.empty()
np.empty_like()

# N*Nの単位行列の生成
np.eye(N)
np.identity(N)
  • 具体例
np.arange(3)
>>> array([0, 1, 2])

np.zeros(10)
>>> array([ 0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.])

np.zeros((3, 5))
>>> array([[ 0.,  0.,  0.,  0.,  0.],
       [ 0.,  0.,  0.,  0.,  0.],
       [ 0.,  0.,  0.,  0.,  0.]])

data = [[1, 2], [3, 4]]
np.zeros_like(data)
>>> array([[0, 0], [0, 0]])

np.ones((3, 5))
>>> array([[ 1.,  1.,  1.,  1.,  1.],
       [ 1.,  1.,  1.,  1.,  1.],
       [ 1.,  1.,  1.,  1.,  1.]])

np.empty(2)
>>> array([  6.92034921e-310,   6.92034921e-310])

np.eye(3)
>>> array([[ 1.,  0.,  0.],
       [ 0.,  1.,  0.],
       [ 0.,  0.,  1.]])

ndarray 要素のデータ型

ndarrayのdtypeを変更(キャスト)

SQLでデータを取ってきた時に数値が文字列型で格納されてる!数値型に直したい!みたいな時に使えそう

  • 書式
ndarray.astype(型名)
np.array( ['1', '2', '3']).astype('float')
>>> array([ 1.,  2.,  3.])

ndarray スカラー計算

ループを書かなくて良いので便利

  • 同じサイズのndarrayの演算
    同位置の要素同士で計算
arr = np.array([[1, 2, 3], [4, 5, 6]])

arr*2
>>> array([[ 2,  4,  6],
       [ 8, 10, 12]])

arr - arr
>>> array([[0, 0, 0],
       [0, 0, 0]])

arr * arr
>>> array([[ 1,  4,  9],
       [16, 25, 36]])
  • 異なるサイズのndarrayの演算(= ブロードキャスト)

インデックス参照、スライシング

基本
  • 書式
arr[i:n]
iからn-1番までを抽出

2次元配列の時
arr[i]
arr[i, j]
arr[i][j]
  • 注意点
    スライスはデータの一部のコピーではなく、スライスを変更するとオリジナルのndarrayも変更されてしまう。
    (スライスはndarrayのビューである、という)
    コピーしたい場合は
arr[i:j].copy()
スライスによるインデックス参照
arr2d = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]])
>>> array([[1, 2, 3],
       [4, 5, 6],
       [7, 8, 9]])

3×3の配列を使って説明していく。

  • スライスでインデックス指定
    次元が下がらない
arr2d[2:, :]
>>> array([[7, 8, 9]])

arr2d[2:, :].shape
>>> (1, 3)
  • スカラーでインデックス指定
    次元が下がる
arr2d[2]
>>> array([7, 8, 9])

arr2d[2].shape
>>> (3,)

7, 8, 9か[7, 8, 9]かという微妙な違い。微妙ゆえに間違えやすいので注意

ブールインデックス参照


  • 以下のようなデータを使う。namesのそれぞれの要素が、dataのそれぞれの行に対応しているとする。
names = np.array(['satou', 'suzuki', 'tanaka'])

data = np.array([['satou1', 'satou2', 'satou3'], ['suzuki1', 'suzuki2', 'suzuki3'], ['tanaka1', 'tanaka2', 'tanaka3']])
>>> array([['satou1', 'satou2', 'satou3'],
       ['suzuki1', 'suzuki2', 'suzuki3'],
       ['tanaka1', 'tanaka2', 'tanaka3']],
      dtype='<U7')
# satouさんのデータのみ取り出したい時、
names == 'satou'
>>> array([ True, False, False], dtype=bool)

data[names == 'satou']
>>> array([['satou1', 'satou2', 'satou3']],
      dtype='<U7')

# satouさん以外のデータのみ取り出したい時、
data[names != 'satou']
>>> array([['suzuki1', 'suzuki2', 'suzuki3'],
       ['tanaka1', 'tanaka2', 'tanaka3']],
      dtype='<U7')
# これでも同じ
data[-(names == 'satou')]

# 複数条件
# | がor
# & がand
(names == 'satou') | (names == 'suzuki')
>>> array([ True,  True, False], dtype=bool)

data[(names == 'satou') | (names == 'suzuki')]
>>> array([['satou1', 'satou2', 'satou3'],
       ['suzuki1', 'suzuki2', 'suzuki3']],
      dtype='<U7')

# 条件指定かつ要素指定
data[names == 'satou', 1:]
>>> array([['satou2', 'satou3']],
      dtype='<U7')

data[names == 'satou', 1]
>>> array(['satou2'],
      dtype='<U7')


# 条件つき代入
# satouさんのデータのみを全て0にする
data[names=='satou'] = 0
>>> array([['0', '0', '0'],
       ['suzuki1', 'suzuki2', 'suzuki3'],
       ['tanaka1', 'tanaka2', 'tanaka3']],
      dtype='<U7')
  • 注意点

ブールインデックス参照で抽出されたデータは、元データのコピー

ファンシーインデックス参照

インデックス参照に整数配列をもちいる方法のこと。
元データのコピーを返す。
- 基本 以下のような配列を使う

arr
>>> array([[ 0.,  0.,  0.,  0.],
       [ 1.,  1.,  1.,  1.],
       [ 2.,  2.,  2.,  2.],
       [ 3.,  3.,  3.,  3.],
       [ 4.,  4.,  4.,  4.]])
# ndarrayから特定の順序で行を抽出
arr[[2, 3]]
>>> array([[ 2.,  2.,  2.,  2.],
       [ 3.,  3.,  3.,  3.]])

# 負のインデックスだと、、?
arr[[-2, -3]]
>>> array([[ 3.,  3.,  3.,  3.],
       [ 2.,  2.,  2.,  2.]])
  • 2次元配列に対するファンシーインデックス参照 以下のような2次元配列を使う
arr
>>> array([[ 0,  1,  2],
       [ 3,  4,  5],
       [ 6,  7,  8],
       [ 9, 10, 11],
       [12, 13, 14]])
arr[[0, 1], [2, 2]]
>>> array([2, 5])

不思議な挙動。0行2列の要素2と、1行2列の要素5を返す。

転置

ビューを返す。
コピーは作らない。
- 書式

# いわゆる転置
arr.T
# 軸1、軸2の順に軸とする
arr.transpose(軸1, 軸2)
# 軸1と軸2を交換
arr.swapaxes(軸1, 軸2)
  • 例(2次元)
arr
>>> array([[ 0,  1,  2,  3,  4],
       [ 5,  6,  7,  8,  9],
       [10, 11, 12, 13, 14]])

arr.T
>>> array([[ 0,  5, 10],
       [ 1,  6, 11],
       [ 2,  7, 12],
       [ 3,  8, 13],
       [ 4,  9, 14]])

arr.transpose(0, 1)
>>> array([[ 0,  1,  2,  3,  4],
       [ 5,  6,  7,  8,  9],
       [10, 11, 12, 13, 14]])

arr.transpose(1, 0)
>>> array([[ 0,  5, 10],
       [ 1,  6, 11],
       [ 2,  7, 12],
       [ 3,  8, 13],
       [ 4,  9, 14]])

arr.swapaxes(0, 1)
>>> array([[ 0,  5, 10],
       [ 1,  6, 11],
       [ 2,  7, 12],
       [ 3,  8, 13],
       [ 4,  9, 14]])

arr.swapaxes(1, 0)
>>> array([[ 0,  5, 10],
       [ 1,  6, 11],
       [ 2,  7, 12],
       [ 3,  8, 13],
       [ 4,  9, 14]])

ユニバーサル関数

universal function(ufunc)
ndarrayを引数に、各要素に作用する関数

  • 単項ufunc
    引数に1つのndarrayをとるufunc
# 絶対値
abs()
fabs()

# 平方根
sqrt()
arr**0.5

# 2乗
square()
arr**2

exp

log
log10
log2
log1p


  • 二項ufunc

引数に2つのndarrayをとるufunc




ndarray データ処理

ndarray ファイル入出力

行列計算

乱数生成