Pythonでのベクトル化とは?NumPyによる高速な配列演算の基礎を解説
本記事では、Python 3.xにおける「ベクトル化(Vectorization)」の概念と、その実装に用いられるさまざまなテクニックについて解説します。ループ処理を排除した効率的なコードの書き方を、具体例とともに見ていきましょう。
ベクトル化とは何か?
ベクトル化とは、ループを使用せずに配列操作を実装するテクニックです。関数を活用することで、コードの実行時間や計算時間を大幅に短縮できます。
ベクトル化では、配列に対して個別に処理を行うのではなく、ベクトル全体に対して一括で演算を実行します。代表的な演算には以下のようなものがあります。
- ドット積(内積・スカラー積):2つのベクトルから単一のスカラー値を出力する演算
- アウター積(外積):結果として、ベクトルの長さ × 長さ の次元を持つ正方行列を生成する演算
- 要素ごとの乗算(Element-wise multiplication):同じインデックスの要素同士を掛け合わせる演算。行列の次元は変化しません
ドット積(内積)の実装例
それでは、従来のループ処理とNumPyによるベクトル化処理を比較してみましょう。以下のコードでは、10万〜30万の整数を持つ2つの配列のドット積を、それぞれの方法で計算し、処理時間を測定しています。
サンプルコード
import time
import numpy
import array
p = array.array('q')
for i in range(100000, 200000):
p.append(i)
q = array.array('q')
for i in range(200000, 300000):
q.append(i)
# 従来の方法:ループによるドット積
tic = time.process_time()
dot_value = 0.0
for i in range(len(p)):
dot_value += p[i] * q[i]
toc = time.process_time()
print("dot_product of vector arrays = " + str(dot_value))
print("Computation time taken = " + str(1000 * (toc - tic)) + "ms")
# ベクトル化:NumPyによるドット積
n_tic = time.process_time()
n_dot_product = numpy.dot(p, q)
n_toc = time.process_time()
print("\nn_dot_product of vector arrays = " + str(n_dot_product))
print("Computation time taken = " + str(1000 * (n_toc - n_tic)) + "ms")
実行結果
dot_product of vector arrays = 3833313333350000.0 Computation time taken = 116.51723400000068ms n_dot_product of vector arrays = 3833313333350000 Computation time taken = 2.5412239999997865ms
この結果を見ると、NumPyの dot() 関数を使ったベクトル化処理は、ループ処理と比較して約40倍以上高速であることがわかります。これは、NumPyが内部でC言語レベルの最適化された演算を行っているためです。
主要な関数の解説
ここで、上記のコードで使用した主な関数について詳しく見ていきます。
- outer(a, b):2つのNumPy配列を引数として受け取り、2つのベクトルのアウター積(外積)を返します。
- multiply(a, b):2つのNumPy配列を引数として受け取り、要素ごとの乗算(アダマール積)の結果を返します。
- dot(a, b):2つのNumPy配列を引数として受け取り、ドット積(内積)を返します。
- zeros((n, m)):形状とデータ型を引数として受け取り、指定された形状と型のゼロで初期化された行列を返します。
- process_time():現在のプロセスのシステムCPU時間とユーザーCPU時間の合計値(小数秒)を返します。スリープ中の経過時間は含まれません。
まとめ
本記事では、Pythonにおけるベクトル化の基本概念と、NumPyを活用した高速な配列演算の方法について学びました。ループ処理をベクトル化された演算に置き換えることで、コードの可読性が向上するだけでなく、実行速度も大幅に改善されます。大規模な数値計算やデータ処理を行う際には、ぜひベクトル化を活用してみてください。
-
【初心者向け】Pythonでラップタイマーを作成する方法を解説
Pythonを使ってストップウォッチのような「ラップタイマー」を作成するには、標準ライブラリの time モジュールが便利です。この記事では、Enterキーを押すたびにラップ時間を計測し、Ctrl+Cで計測を終了できるシンプルなラップタイマーの実装方法を、サンプルコードとともにわかりやすく解説します。ラップタイマーの仕組み基本的な仕組みは以下のとおりです。あらかじめラップ数は固定せず、無限ループで計測を続けるtry-exceptブロックを使い、Ctrl+C(KeyboardInterrupt)で安全に終了する現在時刻と開始時刻・前回ラップ時刻の差分から、合計時間とラップ時間を算出するサンプルコ
-
Pythonで時系列データをプロットする方法をわかりやすく解説
Pythonのmatplotlibを使えば、時系列データ(日時を軸にしたデータ)を簡単にグラフ化できます。ここでは、datetimeオブジェクトを含むデータを折れ線グラフとして描画する基本的な手順を紹介します。 時系列プロットの基本手順 numpyを使用して、x軸(日時データ)とy軸(数値データ)を作成します。 plot()メソッドを使って、作成したx・yのデータをプロットします。 show()メソッドを実行して、図を画面に表示します。 コード例 以下のサンプルコードでは、2021年1月1日の0時から23時までの24個の日時データを生成し、それに対応するランダムな数値をy軸としてプロットし