ぜろといち

ポンコツ理系大学院生による雑多なブログ

numpyとmatplotlibメモ1

numpyとmatplotlibを使った基本的なもののメモがき。

np.cov()

分散共分散行列を計算する

In [1]: import numpy as np

In [2]: a = np.array([[10, 5, 2, 4, 9, 3, 2],[10, 2, 8, 3, 7, 4, 1]])

In [3]: # 1行目を各生徒の数学の点数、2行目を各生徒の国語の点数(それぞれ10点満点)としている。

In [4]: np.cov(a) # まずは引数だけ指定する。  
Out[4]:
array([[ 10.66666667,   6.66666667],
       [  6.66666667,  11.33333333]])

In [5]: c = np.array([3, 2, 1, 5, 7, 2, 1]) # 今度は英語の点数を追加する。

In [6]: np.cov(a,c) # 数学、国語、英語の共分散行列が返される。
Out[6]:
array([[ 10.66666667,   6.66666667,   4.66666667],
       [  6.66666667,  11.33333333,   1.66666667],
       [  4.66666667,   1.66666667,   5.        ]])

NumPyの共分散を求める関数np.cov関数の使い方 - DeepAge

共分散について

共分散の意味と簡単な求め方 | 高校数学の美しい物語

共分散は偏差の積の期待値なので
共分散が大きい(正)→ X が大きいとき Y も大きい傾向がある
共分散が 0 に近い→ X と Y にあまり関係はない
共分散が小さい(負)→ X が大きいとき Y は小さい傾向がある

確率変数たちが互いに独立な場合,共分散は全て 0 になります。(独立なら無相関)
つまり,分散共分散行列の非対角成分は 0 になるので,この場合には分散共分散行列は対角行列になります。対角成分には分散(=固有値)が並びます。

分散共分散行列の定義と性質 | 高校数学の美しい物語

しかし分散共分散はスケールに対して普遍ではないので、実際には共分散を規格化したい相関係数を用いる。

相関係数の数学的性質とその証明 | 高校数学の美しい物語

二組の対応するデータ (X,Y) に対して,相関係数 \rho を以下で定義する:  \displaystyle
\rho=\frac{Cov(X,Y)}{\sigma_X\sigma_Y}

性質:  -1 \leq \rho \leq 1

相関係数は X と Y の関係を表す量で,−1 以上 1 以下です。共分散と同様に,
相関係数が大きい(1に近い)→ X が大きいとき Y も大きい傾向がある
相関係数が0に近い→ X と Y にあまり関係はない
相関係数が小さい(-1に近い)→ X が大きいとき Y は小さい傾向がある
と言うことができます。

逆行列

np.linalg.inv(行列)を使う。
NumPyで逆行列を求めるlinalg.invの使い方 - DeepAge

In [2]: a = np.random.randint(-9, 10, size=(2 ,2)) # まずは2×2の行列から

In [3]: a
Out[3]:
array([[-4,  2],
       [ 7,  2]])

In [4]: np.linalg.inv(a) # 逆行列を求める。
Out[4]:
array([[-0.09090909,  0.09090909],
       [ 0.31818182,  0.18181818]])

In [7]: np.dot(a, np.linalg.inv(a)) # 積をとって単位行列となるか確かめてみる。
Out[7]:
array([[  1.00000000e+00,  -5.55111512e-17],
       [  1.11022302e-16,   1.00000000e+00]])

ndarrayからリストへの変換

tolist()を使う

>>> a = np.array([1, 2])
>>> a.tolist()
[1, 2]
>>> a = np.array([[1, 2], [3, 4]])
>>> list(a)
[array([1, 2]), array([3, 4])]
>>> a.tolist()
[[1, 2], [3, 4]]

numpy.ndarray.tolist — NumPy v1.15 Manual

乱数生成

Numpyによる乱数生成まとめ - Qiita

rand

0~1の一様乱数を生成

randn

標準正規分布 (平均0, 標準偏差1)を生成

normal

標準正規分布ガウス分布)で平均・分散を指定したい場合に使用

choice

リストからランダムに抽出

連番や等差数列を生成するnumpy.arange関数

連番や等差数列を生成するnumpy.arange関数の使い方 - DeepAge

numpy.arange([start, ]stop, [step, ]dtype = None)
params:


|パラメータ名| 型 |概要 |
|start |intまたはfloat |(省略可能)初期値0 生成する等差数列の最初の項を設定します。これを指定しないと0から始まる等差数列が生成されます。 |
|stop |intまたはfloat |生成する等差数列の終点を指定します。 |
|step |intまたはfloat |(省略可能) 初期値1 生成される数列の1つ1つの項間における差を指定します。(公差)|
dtype |dtype |(省略可能)初期値None 生成される数列のデータ型を指定します。これを指定しないとstartやstopで入力したデータ型がそのまま適用されます。 |

In [1]: import numpy as np

In [2]: np.arange(5) # 0~5の等差数列(ただし引数として指定した5は数列の範囲に含まれない)
Out[2]: array([0, 1, 2, 3, 4])

In [3]: np.arange(-10) # 負の値を指定すると要素を持たない配列が返される。
Out[3]: array([], dtype=int64)

In [4]: np.arange(4.5) # floatの形式でも配列は生成される。
Out[4]: array([ 0.,  1.,  2.,  3.,  4.])
In [5]: np.arange(1, 8)
Out[5]: array([1, 2, 3, 4, 5, 6, 7])

In [6]: np.arange(2, 10)
Out[6]: array([2, 3, 4, 5, 6, 7, 8, 9])

In [7]: np.arange(0.5, 5.5) # 小数点以下まで設定しても配列は生成される。
Out[7]: array([ 0.5,  1.5,  2.5,  3.5,  4.5])

In [8]: np.arange(0.55, 5.55)
Out[8]: array([ 0.55,  1.55,  2.55,  3.55,  4.55])
In [9]: np.arange(2, 12, 2) # 初項2,公差2で終点が12の等差数列
Out[9]: array([ 2,  4,  6,  8, 10])

In [10]: np.arange(2, 5, 0.2) # 公差は整数でなくともよい。
Out[10]:
array([ 2. ,  2.2,  2.4,  2.6,  2.8,  3. ,  3.2,  3.4,  3.6,  3.8,  4. ,
        4.2,  4.4,  4.6,  4.8])

In [11]: np.arange(5, 2, -1) # 公差は負の値を指定することができる。
Out[11]: array([5, 4, 3])


In [12]: np.arange(stop = 3, step = 1) # startを指定しないとエラーが返ってくる。
---------------------------------------------------------------------------
( エラーメッセージが表示される)

TypeError: Required argument 'start' (pos 1) not found

行列の連結

np.concatenateを使う

numpy.concatenate — NumPy v1.15 Manual

>>> a = np.array([[1, 2], [3, 4]])
>>> b = np.array([[5, 6]])
>>> np.concatenate((a, b), axis=0)
array([[1, 2],
       [3, 4],
       [5, 6]])
>>> np.concatenate((a, b.T), axis=1)
array([[1, 2, 5],
       [3, 4, 6]])
>>> np.concatenate((a, b), axis=None)
array([1, 2, 3, 4, 5, 6])
  • axisは配列において1番外側のカッコからみてどの部分を結合するかをみている。

  • 配列を形状変換するNumPyのreshape

配列を形状変換するNumPyのreshapeの使い方 - DeepAge

In [1]: import numpy as np

In [2]: a = np.arange(12) # 1つ1次元配列を生成。

In [3]: a
Out[3]: array([ 0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11])

In [4]: b = np.reshape(a, (3, 4)) # 3×4の2次元配列に変形。

In [5]: b  # しっかり変形ができているか確認。
Out[5]:
array([[ 0,  1,  2,  3],
       [ 4,  5,  6,  7],
       [ 8,  9, 10, 11]])

axis指定について

NumPyでのaxis指定 - Qiita

要素の和を求めるNumPyのsum関数

axisに注意

要素の和を求めるNumPyのsum関数の使い方 - DeepAge

In [22]: a # 先ほどと同じ配列を使い回す。s
Out[22]:
array([[4, 6, 8, 3, 3],
       [9, 4, 6, 5, 4]])

In [23]: b
Out[23]: array([2, 4, 1, 6])

In [24]: c
Out[24]:
array([[[5, 0, 9, 8, 4],
        [6, 2, 8, 5, 3],
        [9, 7, 4, 8, 6],
        [2, 4, 2, 0, 7]],

       [[1, 4, 4, 3, 3],
        [8, 6, 6, 2, 7],
        [0, 0, 2, 4, 7],
        [5, 0, 2, 7, 9]]])

In [25]: a.sum() # まずは単純な和から
Out[25]: 52

In [26]: b.sum()
Out[26]: 13

In [27]: c.sum()
Out[27]: 179

In [28]: a.sum(axis=0) # axisを指定する
Out[28]: array([13, 10, 14,  8,  7])

In [29]: c.sum(axis=0)
Out[29]:
array([[ 6,  4, 13, 11,  7],
       [14,  8, 14,  7, 10],
       [ 9,  7,  6, 12, 13],
       [ 7,  4,  4,  7, 16]])

In [30]: c.sum(axis=2)
Out[30]:
array([[26, 24, 34, 15],
       [15, 29, 13, 23]])

In [31]: a.sum(axis=0, keepdims=True) # keepdims=Trueにする
Out[31]: array([[13, 10, 14,  8,  7]])

In [32]: c.sum(axis=2, keepdims=True)
Out[32]:
array([[[26],
        [24],
        [34],
        [15]],

       [[15],
        [29],
        [13],
        [23]]])

In [33]: a.sum(axis=0, dtype='float') # dtypeを指定する
Out[33]: array([ 13.,  10.,  14.,   8.,   7.])

numpy.random.normal

numpy.random.normal — NumPy v1.15 Manual

ガウス分布正規分布) numpy.random.normal(loc=0.0, scale=1.0, size=None)
Draw random samples from a normal (Gaussian) distribution.

>>> mu, sigma = 0, 0.1 # mean and standard deviation
>>> s = np.random.normal(mu, sigma, 1000)

行列の抽出

[Python]Numpyの参照、抽出、結合 - Qiita

In [17]: X = np.arange(25).reshape(5,5)

In [18]: print X
[[ 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]]

In [19]: print X[3,2]
17

In [20]: print X[-1,-2]
23

In [59]: print X[1:3,0:2]
[[ 5  6]
 [10 11]]

In [60]: print X[1:3,::-1]
[[ 9  8  7  6  5]
 [14 13 12 11 10]]

#行の抽出
In [21]: print X[1]
[5 6 7 8 9]

In [22]: print X[1,]
[5 6 7 8 9]

In [23]: print X[1,:]
[5 6 7 8 9]

#列の抽出
In [24]: print X[:,1]
[ 1  6 11 16 21]

要素が1の配列を生成するnumpy.ones関数

要素が1の配列を生成するnumpy.ones関数の使い方 - DeepAge

In [4]: np.ones(4, dtype="float32") # データ型を"float32"にする。
Out[4]: array([ 1.,  1.,  1.,  1.], dtype=float32)

In [5]: np.ones(4, dtype="int8") # データ型を"int8"にする。
Out[5]: array([1, 1, 1, 1], dtype=int8)

In [6]: np.ones((2,3), dtype = "complex") # 複素数の形にすることもできる。
Out[6]:
array([[ 1.+0.j,  1.+0.j,  1.+0.j],
       [ 1.+0.j,  1.+0.j,  1.+0.j]])

リストのコピー

リストのコピーはdeepcopyが多分ベター 入れ子も含めてコピーしてくれる

qiita.com

from copy import deepcopy
x = [[1, 2, 3], 4, 5]
y = deepcopy(x)
y[0][0] = 999
x

>>> [[1, 2, 3], 4, 5]

cumsumとdiff

deepage.net

diffは隣の要素同士の差を格納
cumsumは要素ごとに足していってそこまでの和を格納

seed

numpy.random.seed — NumPy v1.15 Manual

numpy.random.seed(seed=None)

乱数を初期化する。seedに特定の数字を入れれば決まった乱数を毎回生成できる。

matplotlibで線グラフの描画

[Python]Matplotlibで線グラフを描画する方法 - Qiita

簡単な線グラフの描画

import numpy as np
import matplotlib.pyplot as plt
from scipy.stats import norm

fig = plt.figure()
ax = fig.add_subplot(1,1,1)

x = np.linspace(-6,6,1000)

ax.plot(x,norm.pdf(x, loc=0.0, scale=1.0), color='black',  linestyle='solid')
ax.plot(x,norm.pdf(x, loc=0.0, scale=0.5), color='black',  linestyle='dashed')
ax.plot(x,norm.pdf(x, loc=0.0, scale=0.25), color='black', linestyle='dashdot')

ax.set_title('First line plot')
ax.set_xlabel('x')
ax.set_ylabel('y')
ax.grid(True)
fig.show()

plt.figure()で描画するキャンバスを用意。
x, yに相当する配列を渡す. ax.grid(True)で図にグリッド線入れる。 colorで線の色指定、linestyleで線のスタイルが指定できる。

https://camo.qiitausercontent.com/44b13ab1c5bfe376c5a9d796b593358eba983e85/68747470733a2f2f71696974612d696d6167652d73746f72652e73332e616d617a6f6e6177732e636f6d2f302f3130303532332f36633332626335322d653535372d663361652d646361652d6235326165646566323632352e706e67

線の太さ変更

linewidthで変えられる

import numpy as np
import matplotlib.pyplot as plt
from scipy.stats import norm

fig = plt.figure()
ax = fig.add_subplot(1,1,1)

x = np.linspace(-6,6,1000)

ax.plot(x,norm.pdf(x, loc=0.0, scale=1.0), color='black',  linestyle='solid', linewidth = 3.0, label='line1')
ax.plot(x,norm.pdf(x, loc=0.0, scale=0.5), color='black',  linestyle='dashed',linewidth = 1.0, label='line2')
ax.plot(x,norm.pdf(x, loc=0.0, scale=0.25), color='black', linestyle='dashdot', linewidth = 0.5,label='line3')

ax.set_title('Second line plot')
ax.set_xlabel('x')
ax.set_ylabel('y')
ax.legend()
ax.grid(True)
fig.show()

https://camo.qiitausercontent.com/d19984ff970d8f170035f6366596d214ed673726/68747470733a2f2f71696974612d696d6167652d73746f72652e73332e616d617a6f6e6177732e636f6d2f302f3130303532332f65613439366232392d633031342d353437612d623131312d3334633066663635306465302e706e67

makerの描画

markerを指定すると線グラフのデータの場所にmarkerが描画される。データが多い場合は、下の線のようにmarkerで線が見えなくなる。markeveryを指定することで何個間隔でmarkerを描画するか指定できる。

import numpy as np
import matplotlib.pyplot as plt
from scipy.stats import norm

fig = plt.figure()
ax = fig.add_subplot(1,1,1)

x = np.linspace(-6,6,1000)

ax.plot(x,norm.pdf(x, loc=0.0, scale=1.0), color='black',  linestyle='solid', linewidth = 1.0, marker='o')
ax.plot(x,0.5 + norm.pdf(x, loc=0.0, scale=1.0), color='black',  linestyle='solid', linewidth = 1.0, marker='o', markevery = 50)

ax.set_title('4th line plot')
ax.set_xlabel('x')
ax.set_ylabel('y')
ax.grid(True)
fig.show()

https://camo.qiitausercontent.com/e64bea5142bb35743acf2b0a29ab75b414493950/68747470733a2f2f71696974612d696d6167652d73746f72652e73332e616d617a6f6e6177732e636f6d2f302f3130303532332f65646636366230632d323830332d363130342d313366662d6566353834306433313163312e706e67

markerの代表的なもの

marker description
. point
o circle
v 下三角
^ 上三角
s 四角
+ plus
x cross
* star