📑

ライブラリ「NumPy」基礎(数値計算)

2023/05/09に公開

[!abstract]+ Curriculum

  1. NumPyとは
  2. データ操作
  3. NumPyとメモリ
  4. Numpyによる統計解析
  5. 今後の学習の進め方
    添削問題

NumPyとは

  • NumPy配列と四則演算
    • ブロードキャスト:演算前にNumPy配列の shape を合わせること。
  • データの読み込み : delimiter, skiprows, usecols
import numpy as np

arr_1 = np.loadtxt("./4002_new_numpy/csv_example.csv",
				   delimiter=",", # 区切り文字をカンマに指定
				   skiprows=1, # 最初の1行をスキップ
				   usecols=[0, 1, 2]) # 使用する列番号を指定 print(arr_1)
  • 特定の行、列に対する計算
import numpy as np

# csv_example(1.2.4参照)を読み込む
arr_1 = np.loadtxt("./4002_new_numpy/csv_example.csv", delimiter=",", skiprows=1, usecols=[0, 1, 2] )
# Heightの列のみ0.394をかける
# arr_2は1行3列の配列
arr_2 = np.array([1, 0.394, 1])
arr_3 = arr_1 * arr_2
# arr_1とarr_3を比較して出力
print('arr_1') 
print(arr_1) 
print('arr_3') 
print(arr_3)

データ操作

  • リストのように抽出
arr_3 = arr_1[::2] # ひとつおきに要素を抽出
  • リストでは不可能な抽出
print(list_1[2][1])
print(arr_1[2, 1])
  • 複数要素抽出
import numpy as np

list_1 = [[1,2],[3,4],[5,6]]
arr_1 = np.array(list_1)

# リストにより複数要素を抽出
print(arr_1[[2, 1]])
>>> 出力結果
[[5 6]
 [3 4]]
  • 3次元以上の配列の軸の入れ替え
import numpy as np

list_1 = [[[1, 2], [3, 4], [5, 6]], [[7, 8], [9, 10], [11, 12]]]
arr_1 = np.array(list_1)

print('軸の入れ替え前 arr_1.shape: ', arr_1.shape)
print(arr_1)

arr_2 = arr_1.transpose(1, 0, 2)
print('arr_1を0軸と1軸の入れ替え後 arr_2.shape: ', arr_2.shape)
print(arr_2)

arr_3 = arr_2.transpose(2, 1, 0)
print('arr_2を0軸と2軸で入れ替え後 arr_3.shape: ', arr_3.shape)
print(arr_3)
>>> 出力結果
軸の入れ替え前 arr_1.shape:  (2, 3, 2)
[[[ 1  2]
  [ 3  4]
  [ 5  6]]

 [[ 7  8]
  [ 9 10]
  [11 12]]]
arr_1を0軸と1軸の入れ替え後 arr_2.shape:  (3, 2, 2)
[[[ 1  2]
  [ 7  8]]

 [[ 3  4]
  [ 9 10]]

 [[ 5  6]
  [11 12]]]
arr_2を0軸と2軸で入れ替え後 arr_3.shape:  (2, 2, 3)
[[[ 1  3  5]
  [ 7  9 11]]

 [[ 2  4  6]
  [ 8 10 12]]]
  • 配列の形変更 reshape : 引数に -1 を入れると自動的に合わせます。
import numpy as np

np.random.seed(1)

# arr_1を作成(ここは変更しないでください)
rand_row, rand_col = np.random.randint(1, 10, 2)
arr_1 = np.random.rand(rand_row, rand_col)

# arr_1のshapeを変更し、arr_2に代入しましょう
arr_2 = arr_1.reshape(-1,1)
print(arr_2)
  • 配列の形変更 **resize
    • in-place 処理

NumPy とメモリ

  • データ型
import numpy as np

arr_1 = np.array([1, 2, 3, 4, 5], dtype=np.int8) # ここでデータ型を「int8」に指定
print(arr_1.dtype) # データ型を確認
print(arr_1)
>>> 出力結果
int8
[1 2 3 4 5]
  • In-place 처리 : .sort(), .resize()

Viewについて

  • 変数にNumPy配列を代入 → その配列の view が作成される (メモリ共有)
  • スライスで一部ビュー可能
  • .copy()はメモリを共有しないコピー生成
import numpy as np


arr_1 = np.array([1, 2, 3, 4, 5])

# arr_1のビューを作成しましょう
arr_2 = arr_1[:2]
arr_2[1] = 100

print(arr_1)
print(arr_2)
>>> 出力結果
[ 1 100 3 4 5]
[ 1 100]

NumPy で統計解析

#np/stats

  • 分散 .var(axis=number)
  • 最大値、最小値のインデックス .argmax(), .argmin()
  • 並べ替えられたインデックス .argsort()
  • numpy.where() 関数 リンク

添削問題

(基本) NumPy処理速度テスト

import numpy as np

# 乱数の初期化
np.random.seed(0)

# 指定された大きさの画像を乱数を用いて生成する関数
# 仮引数mは画像の縦の大きさ、nは画像の横の大きさです
def make_image(m, n):
  # m×n行列の各成分を0~5の値でランダムに満たしてください
  image = np.random.randint(1, 6, size=(m, n))
  return image
  
# 渡された行列の一部を変更する関数
def change_matrix(matrix):
  # 与えられた行列の形を取得し、shapeに代入してください
  shape = matrix.shape
  # 行列の各成分について、変更するかしないかをランダムに決めた上で
  # 変更する場合は0~5のいずれかの整数にランダムに入れ替えてください
  tmp_matrix = matrix.reshape(-1,1)
  for i in range(len(tmp_matrix)):
    if np.random.randint(0,2) == 1:
      tmp_matrix[i] = np.random.randint(1, 5)
  return tmp_matrix.reshape(shape)

# ランダムに画像を作成
image1 = make_image(3, 3)
print(image1)

# ランダムに変更を適用する
image2 = change_matrix(np.copy(image1))
print(image2)

# image1とimage2の差分を計算し、image3に代入してください
image3 = image1 - image2
print(image3)

# image3の各成分が絶対値である行列をもとめimage3に再代入してください
image3 = np.absolute(image3)

# image3を出力
print(image3)

(応用) 単純化した二つの画像の差分計算

  • 0-5のランダムな値を持つ3x3行列(2次元配列=画像)を一つ作ろう。
  • 2番目の画像は、各値を変えるかどうかをランダムに選んだ後、また0-5のランダムな値を付与。
  • その後、2つの画像の差分を求めよう。
import numpy as np

# 乱数の初期化
np.random.seed(0)

# 指定された大きさの画像を乱数を用いて生成する関数
# 仮引数mは画像の縦の大きさ、nは画像の横の大きさです
def make_image(m, n):
  # m×n行列の各成分を0~5の値でランダムに満たしてください
  image = np.random.randint(0, 6, size=(m, n))
  return image

# 渡された行列の一部を変更する関数
def change_matrix(matrix):
  # 与えられた行列の形を取得し、shapeに代入してください
  shape = matrix.shape
  # 行列の各成分について、変更するかしないかをランダムに決めた上で
  # 変更する場合は0~5のいずれかの整数にランダムに入れ替えてください
  tmp_matrix = matrix.reshape(-1,1)
  for i in range(len(tmp_matrix)):
    if np.random.randint(0,2) == 1:
      tmp_matrix[i] = np.random.randint(0, 6)
  return tmp_matrix.reshape(shape)

# ランダムに画像を作成
image1 = make_image(3, 3)
print(image1)

# ランダムに変更を適用する
image2 = change_matrix(np.copy(image1))
print(image2)

# image1とimage2の差分を計算し、image3に代入してください
image3 = image1 - image2
print(image3)

# image3の各成分が絶対値である行列をもとめimage3に再代入してください
image3 = np.absolute(image3)

# image3を出力
print(image3)

Discussion