私的メモ。
Jupyter
環境構築
jupyter_contrib_nbextensions
は、後述する pdf 出力用や、 Jupyter で補完を効かせるためなどに入れるもので、必須ではない
pip install jupyter jupyter_contrib_nbextensions
pip install matplotlib numpy # その他必要な物あれば追加
ブラウザで Jupyter を起動
ブラウザではなく VSCode 内で良いのではないかと思いつつ、結局乗り換えていない。
jupyter notebook --ip=127.0.0.1 --allow-root
Jupyter のテーマを変更する
jupyterthemes
モジュールを入れてもいいし、自分で ~/.jupyter/custom/custom.css
をいじってもいい。
前者の場合
・Jupyter Notebookの背景色やフォントをかっこよく変更する
とかが参考になる。
私は https://gist.github.com/HelloRusk/54f5e0b60e39ae8826bfcc580d524e40 を custom.css として使っている。
Jupyter を pdf として出力する
jupyter nbconvert hoge.ipynb --to pdf
おまじない
import numpy as np
import matplotlib.pyplot as plt
%matplotlib inline
from tqdm.notebook import tqdm
Jupyter Notebook でプログレスバーを出す時は、tqdm.notebook
を使う方が見やすい。
numpy
べき乗
np.power(2, 3) # 8
相関係数
x = np.array([
[1, 2, 1, 9, 10, 3, 2, 6, 7],
[2, 1, 8, 3, 7, 5, 10, 7, 2]])
np.corrcoef(x)
返り値は相関係数行列になっているので、(1, 2)要素(または(2, 1)要素)を確認する。
最大(小)値を取る index
argmax, argmin がある。
np.argmax(arr)
等差数列
リスト内包表記で作っても全然いいのだけど、np.arange
がある。
np.arange(5)
# array([0, 1, 2, 3, 4])
np.arange(3, 10, 2)
# array([3, 5, 7, 9])
指定区間を N 等分した数列
np.linspace(2.0, 3.0, num=5)
# array([2. , 2.25, 2.5 , 2.75, 3. ])
等比数列
np.logspace(3, 7, num=5, base=2)
# array([8, 16, 32, 64, 128])
要素の平均を取る
np.mean
と np.average
のどちらでもよい。
axis=0
では行方向の平均を取る(すなわち N * M
行列が 1 * M
行列になる)。
a = np.array([[33, 44, 54, 23],
[25, 55, 32, 76]])
np.average(a, axis = 0)
# array([ 29. , 49.5, 43. , 49.5])
np.average(a, axis = 1)
# array([ 38.5, 47. ])
# np.mean でも同じ
行列の初期化
引数がタプルであることに注意
np.zeros((3, 4))
全要素を1で初期化するnp.ones
もある。
ベクトルの内積, 行列の積
いずれも np.dot
np.dot(A, B)
@
演算子も使える。
ベクトル・行列の連結
色々紛らわしいので https://note.nkmk.me/python-numpy-concatenate-stack-block/ を見た方がよい。numpy.stack
を使った方が良い説がある。
v1 = np.array([1, 2, 3])
v2 = np.array([4, 5, 6])
np.concatenate([v1, v2])
# [1 2 3 4 5 6]
引数全体がリストである必要がある点に注意
多次元配列を一次元配列につぶす
np.ravel
が組み込みの flatten
よりも速い。
x = np.array([[1, 2, 3], [4, 5, 6]])
np.ravel(x)
# array([1, 2, 3, 4, 5, 6])
ベクトルの長さ(ノルム)
普通使うのは2ノルム
np.linalg.norm(X)
np.linalg.norm(X,ord=1) # 1ノルム
ちなみに、np.linalg.norm
は行列のノルム1 にも対応している。
行列の列の抽出
mat[:,2]
みたいに書く
mat =\
[[ 0 1 2 3 4 5 6 7 8 9]
[10 11 12 13 14 15 16 17 18 19]
[20 21 22 23 24 25 26 27 28 29]
[30 31 32 33 34 35 36 37 38 39]
[40 41 42 43 44 45 46 47 48 49]
[50 51 52 53 54 55 56 57 58 59]
[60 61 62 63 64 65 66 67 68 69]
[70 71 72 73 74 75 76 77 78 79]
[80 81 82 83 84 85 86 87 88 89]
[90 91 92 93 94 95 96 97 98 99]]
mat[:,2]
# array([ 2, 12, 22, 32, 42, 52, 62, 72, 82, 92])
配列から特定の要素を削除
test = np.array([1, 2, 3, 4, 5])
np.delete(test, [1, 3])
# array([1, 3, 5])
スライスとして削除することはできない!!
単位行列
np.identity(5)
np.eye(5)
どっちでもいい。
逆行列
np.linalg.inv(A)
転置行列
A.T
行列式
np.linalg.det(A)
固有値・固有ベクトル
関数 | 説明 |
---|---|
np.linalg.eig | 一般行列の固有値・固有ベクトル |
np.linalg.eigh | エルミートor実対称行列の固有値・固有ベクトル |
np.linalg.eigvals | 一般行列の固有値 (固有ベクトルは計算しない) |
np.linalg.eigvalsh | エルミートor実対称行列の固有値 (固有ベクトルは計算しない) |
対称行列では固有値を求めるアルゴリズムが一般行列と異なるので、精度のためにも、対称行列では eigh, eigvalsh を使うようにする。
なお、固有値と固有ベクトルを両方求めるメソッドでは、返り値が (固有値, 固有ベクトル)
のタプルとして返ってくる。
一般化固有値問題を解きたい場合は scipy.linalg.eig
を用いる。
from scipy import linalg
linalg.eig(A, B)
なお、固有ベクトルを取る際は縦ベクトルを取る必要があることに注意!!!
すなわち、i
番目の固有値 w[i]
に対応する固有ベクトルは v[:,i]
となる。
乱数
正規分布に従う乱数
np.random.normal(size = 1000000)
np.random.normal(loc=1.0, scale=2.0, size=20)
多変量正規分布の場合、multivariate_normal
を使う
mean = (1, 2)
cov = [[1, 0], [0, 1]]
np.random.multivariate_normal(mean, cov, 100)
一様分布に従う乱数
np.random.uniform(size = 1000000)
np.random.uniform(low=1.0, high=2.0, size=20)
値をひとつ返したい時は
np.random.rand()
とする。
カイ二乗分布に従う乱数
np.random.chisquare(2, 10000)
その他雑多なネタ
連立一次方程式を解く
a = np.array([[3,1], [1,2]])
b = np.array([9,8])
np.linalg.solve(a, b)
# array([2., 3.])
行列の変形
(1, 12)サイズの行列を(3, 4)サイズに変形するとか。
a = array([ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11])
np.reshape(a, (3, 4))
# array([[ 0, 1, 2, 3],
# [ 4, 5, 6, 7],
# [ 8, 9, 10, 11]])
条件数
数値解析で、誤差の影響の受けやすさの指標となる値(値が大きいと誤差に弱いことが言える)
np.linalg.cond(A, 2)
matplotlib
基本的なグラフ
plt.figure(figsize=(8, 6)) # 横8×縦6のグラフ
plt.title("This is title.") # グラフにタイトルを付ける
# 軸に名前を付ける
plt.xlabel("試行回数")
# 軸の範囲を変更する
plt.ylim(0, 2.5)
# label= で凡例、color= で色、linestyle= で線のスタイルを変更
plt.plot(X, Y, label="one")
plt.plot(X2, Y2, label="two")
plt.legend()
plt.show()
対数グラフ
plt.yscale('log')
で y 軸が log スケールになる。
ヒストグラム
plt.hist(x, bins=100)
bins
はビン数(階級の数)
散布図
plt.scatter(x, y, marker='x', c='red')
等高線
最適化の様子を描く時とかで、補助的に等高線を入れたいことがある。
x = np.linspace(-1, 1, 100)
y = np.linspace(-1, 1, 100)
X, Y = np.meshgrid(x, y)
Z = np.sqrt(X**2 + Y**2)
plt.contour(X, Y, Z)
plt.gca().set_aspect('equal')
等高線はかなり難しいので http://ailaby.com/contour/ をよく読んだ方がいい。
その他 Python コーディングテクニック
ファイルを一行ずつ処理
f = open("sample.txt", "r")
for line in f:
# example
print(line.strip())
# strip() はデフォルトでは両端の空白文字を取り除く
f.close()
複数の list をまとめてループ(zip)
names = ['Alice', 'Bob', 'Charlie']
ages = [24, 50, 18]
for name, age in zip(names, ages):
print(name, age)
# Alice 24
# Bob 50
# Charlie 18
インデックス付きループ(enumerate)
l = ['Alice', 'Bob', 'Charlie']
for i, name in enumerate(l):
print(i, name)
# 0 Alice
# 1 Bob
# 2 Charlie
format 文
print("i={} lambda={} x={}".format(i, l, x))
あるいは
print(f"i={i} lambda={l} x={x}")
数学関数
一般的な関数は numpy のものでなくとも普通に math
モジュールにある。詳しくは https://docs.python.org/ja/3/library/math.html を確認
from math import sin, cos, pi, exp