LoginSignup
0
1

More than 1 year has passed since last update.

レポートで使う Python 大全(numpy や matplotlib など)

Last updated at Posted at 2019-12-25

私的メモ。

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.meannp.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
0
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
1