Python NumPy¶
はじめに¶
Pythonは、すべてのデータ(整数値、浮動小数点数値も)がオブジェクトとしてメモリ上に生成・配置され、メモリ管理の対象となります。
数値計算の分野では、多数のデータを配列に格納し演算のためにこれらをまとめて読み書きします。C言語などでは言語標準で配列を提供していますが、Pythonは配列を型として提供しておらず、配列の代替えとしてリストを使います。リストではデータ1個1個がオブジェクトとして独立にメモリ上に管理され、要素をまとめてアクセスする場合、配列に比べて非常に効率が悪くなります(例、メモリの局所性がないとキャッシュミスが起きてCPUの演算性能低下を招いてしまう)。
NumPyは、データをC言語で記述されたライブラリ側で配列に格納し演算することでPythonメモリ管理の性能問題を回避します。またベクトル演算のAPIを介して1回の関数呼び出しで複数の値をまとめて演算することで、ループ制御が不要となりコードが簡潔になるとともにPythonのアプリケーションとC言語で実装したNumPyライブラリ側のインタフェースが少なくなりPythonとC言語間のオーバーヘッドを減らしています。
一方で、NumPyを活用したプログラムは、ベクター(配列)とその計算を主体とした記述となるので、いわゆるPythonらしいコードとはちょっと異なります。このあたりは数値計算、データ処理といった用途に特化したコードと割り切って使うのがよさそうです。
例)円周のプロット¶
円周上に100個の点を生成し、matplotlibのグラフに点を線で結ぶグラフを表示するソースコードを、Python標準とnumpyとを使った場合で比較してみます。

Python標準¶
import math
import matplotlib.pyplot as plt
x = [] # Python標準ライブラリのリスト
y = []
for t in range(0, 101): # 整数0から100まで1ずつ増やして順番に生成
theta = math.pi * 2 * t / 100 # 0から2πの範囲を100区分した値をtに応じて生成
x.append(math.cos(theta))
y.append(math.sin(theta))
plt.plot(x, y, '.-') # ポイントを小さい丸でプロットしポイント間を線で結ぶ
plt.grid()
plt.gca().set_aspect('equal')
plt.show()
- Pythonの標準数学ライブラリのsin/cosは、スカラー(単一の値)を入力し計算し出力するので、生成する点の数だけループ制御をする
- 配列の代替えとするリストに点を生成するたびに追加(append)する
NumPy使用¶
import numpy as np
import matplotlib.pyplot as plt
theta = np.linspace(0, 2 * np.pi, 100) # 初期値、最大値、区分数を指定し数列の配列を生成
x = np.cos(theta) # 100個の角度を入れてそのcos値を100個生成(theta, xはnumpy配列)
y = np.sin(theta) # 同上
plt.plot(x, y, '.-')
plt.grid()
plt.gca().set_aspect('equal')
plt.show()
- NumPyの数学ライブラリのsin/cosは、ベクター(複数の値)を入力し計算し出力するので、生成する点の数を格納した配列(ndarray)を一回の呼び出しで完結し、ループ制御は不要
- 配列への値の追加処理も記述不要
インストールとセットアップ¶
pip install numpy
ただし、NumPyは他のライブラリ(Pandas等)で使われることも多く、そうしたライブラリをinstallした時に合わせてインストールされていることがあります。
import numpy
慣習的に、npの略名でエイリアスしてインポートすることもあります。import numpy as np
データ型¶
ndarray¶
多次元配列のndarray型が提供されます。配列の要素は全て同じ型である必要があります。
ndarrayの要素の型¶
int8, uint8, int16, uint16, int32, uint32, int64, uint64, float16, float32, float64, float128, complex64, complex128, complex256, bool, object, string_, unicode_
1次元のndarray¶
array関数を使って、引数のシーケンスからndarrayを生成する。
arr = np.array([1, 3, 5])
配列の要素の型は自動推論され、この場合はint64となりました。
arr = np.array([1.5, 3, 5]) とすると、配列の要素の型はfloat64となりました。
要素の型を指定して配列を生成することができます。
arr = np.array([1, 3, 5], dtype=np.float64)
2次元の要素の型¶
arr = np.array([1, 2, 3], [4, 5, 6])
matrix¶
T.B.D.
演算¶
ベクトル¶
単位ベクトル¶
長さ1のベクトルを求めます。直接生成するAPIはないので、ベクトルのnorm(長さ)を求めてから、ベクトルをその長さで除算して求めます。
vector = np.array([1, 3, 5])
norm = np.linalg.norm(vector)
unit_vector = vector / norm
外積¶
numpy.cross で外積の計算ができます。
行列¶
行列とベクトルの積¶
演算子 @ を用います。