Chapter 10

python

Subsections of python

Animation

FuncAnimation

def plot(i, *fargs):
    plt.cla()
    y = fargs[]
    ax.plot(x, y)
    
fig = plt.figure()
ax = fig.add_subplot(111)
fargs = (np.arange(10))
anim = FuncAnimation(fig, plot_posture, frames=len(args[0]), interval=100, fargs=fargs)
plt.show()

保存する場合は以下のように書く

anim.save("animation.fig", writer="pillow")

または

anim.save("anim.mp4", writer="ffmpeg", dpi=100)

ffmpegでエラーが出る場合

次のようにffmpegをインストール

$ conda install -c anaconda ffmpeg

Creating dateset by Numpy

データの生成

等差数列の生成

np.arange(start, stop, step)

要素数を指定した等差数列の生成

np.linspace(start, stop, num, endpoint=True)
  • endpoint: stopを数列に含むか否か(デフォルトはTrue)

同じ値で初期化した配列の生成

  • 0で初期化

    np.zeros(shape)
    
    np.zeros_like(arr)
    
  • 1で初期化

    np.ones(shape)
    
    np.ones_like(arr)
    
  • 任意の値 (fill_value) で初期化

    np.full(shape, fill_value)
    
    np.full_like(arr, fill_value)
    
  • 空の配列を生成

    np.empty(shape)
    
    np.empty_like(arr)
    

単位テンソルの生成

np.eye(shape)

Docstring

Python Docstring

  • Docstringとはメソッドやクラスについての説明文(コメント)
  • __doc__というアトリビュート(属性)に格納されている
  • `で書くこともできるが,一般的には"で書く
  • 対話型シェル等の環境でhelp関数を使用することで出力することも可能
  • VS Codeでは関数等にカーソルを合わせることで表示される

Docstringは次のように定義分の先頭に記述する.

def test_func(param1, param2):
    """Summary line.

    Extended description of function.

    Args:
        param1 (int): Description of param1
        param2 (str): Description of param2

    Returns:
        bool: Description of return value

    """
    return True

Docstringの書き方には様々なスタイルが存在している.

Googlesスタイル


#!/usr/bin/python
# -*- coding: utf-8 -*-
"""モジュールの説明タイトル

- ソースコードの一番始めに記載すること
- importより前に記載する

Todo:
    TODOリストを記載
    - conf.pyの``sphinx.ext.todo`` を有効にしないと使用できない
    - conf.pyの``todo_include_todos = True``にしないと表示されない
"""

import json
import inspect

class testClass() :
    """クラスの説明タイトル

    クラスの説明文

    Attributes:
        属性1 (型): 説明
        属性2 (:obj:`型`): 説明.
    """

    def print_test(self, param1, param2) :
        """関数の説明タイトル

        関数の説明文

        Args:
            引数1 (型): 説明
            引数2 (:obj:`型`, optional): 説明.

        Examples:

            関数の使い方

            >>> print_test ("test", "message")
               test message
        """
        return param1*param2

GoogleスタイルではAttributesやArgs, Returns, Yieds, Raises, Examples, Note, Todo という用途別のセクションが存在

  • Attributes: 属性
  • Args: 引数
  • Returns: 返り値
  • Yields: yeild文を使用した関数の返り値
  • Raises: 例外処理
  • Examples: 使用例
  • Note: 注釈
  • Todo: Todoリスト(実装予定の処理など)

関数アノテーション

Python3.0以降では関数アノテーション(Function Annotations)という仕組みが導入され, 関数の引数や返り値に直接型を記述することができる. ただしあくまで注釈のため,(環境によっては処理に使用されることもあるが)実行時に チェックされたりはしない.

def test_func(param1: str, param2: int) -> tuple[str, int]:
    return (param1, param2)

参考

Pickle

pickleの使用方法

Saving

with openでの保存、読み込み

with open("filename.pkl", "wb") as f:
    pickle.dump(data, f)
with open("filename.pkl", "rb") as f:
    hoge = pickle.load(f)

pandasでの保存、読み込み

import pandas as pd
pd.to_pickle(data, "filename.pkl")
hoge = pd.read_pickle("filename.pkl")

joblib(?)での保存、読み込み

joblib.dump(data, "filename.jb", compress=3)
hoge = joblib.load("filename.jb")

Jupyter notebook

セル

  • 編集モードへの変更:ダブルクリックまたは"Enter"
  • コマンドモードへの変更:ESC
  • セルの内容の実行
    • Windows:Ctrl+Enter
    • MacOS:command+Return
    • OS共通:Shift+Enter

Markdownセルとcodeセル

  • Markdownセル:テキストを入力するためのセル
  • Codeセル:Pythonの実行を行うセル

arkdownセルの編集方法

  • “#“でタイトル
  • “##“でサブタイトル
  • “-“で箇条書き
  • 太文字“で太文字

便利なショートカットキー(Window)

コマンドモード

ショートカットキー 説明
F 検索・置換
Ctrl -Shift
Ctrl -Shift
Enter 編集モードにする
P コマンドパレットを開く
Shift -Enter
Ctrl -Enter
Alt -Enter
Y コードセルにする
M マークダウンセルにする
R rawセルにする
1 見出し1にする
2 見出し2にする
3 見出し3にする
4 見出し4にする
5 見出し5にする
6 見出し6にする
K 上のセルを選択する
Up 上のセルを選択する
Down 下のセルを選択する
J 下のセルを選択する
Shift -K
Shift -Up
Shift -Down
Shift -J
A 上にセルを追加する
B 下にセルを追加する
X 選択しているセルをカット
C 選択しているセルをコピー
Shift -V
V 下に貼り付け
Z セルの削除をやり直す
DD 選択しているセルを削除する
Shift -M
Ctrl -S
S 保存する
L 行番号の表示・非表示
O セルの出力結果の表示・非表示
Shift -O
H キーボードショートカット表示
I×2 カーネルをインタラプト
0 カーネルを再起動
Esc ページャーを閉じる
Q ページャーを閉じる
Shift -L
Shift -Space
Space 下にスクロール

編集モード

ショートカットキー 説明
Tab コード補完・タブ
Shift-Tab ツールチップ
Ctrl-] インデント
Ctrl-[ ディデント
Ctrl-A 全選択
Ctrl-Z やり直し
Ctrl-Shift -
Ctrl-Y やり直し
Ctrl-Home セルの最初に移動
Ctrl-Up セルの最初に移動
Ctrl-End セルの最後に移動
Ctrl-Down セルの最後に移動
Ctrl-Left 一単語前に移動
Ctrl-Right 一単語後に移動
Ctrl-Backspace 前の単語を削除
Ctrl-Delete 後の単語を削除
Ctrl-M コマンドモードにする
Ctrl-Shift-F コマンドパレットを開く
Ctrl-Shift-P コマンドパレットを開く
Esc コマンドモードにする
Shift-Enter セルを実行し、下のセルを選択する
Ctrl-Enter セルを実行する
Alt-Enter セルを実行し、下にセルを追加する
Ctrl-Shift-Minus セルを分割する
Ctrl-S 保存する
Down カーソルを下に移動
Up カーソルを上に移動
Ctrl-/ 選択部分をコメントアウト

Kernel

  • セルの左の “In[]” の括弧内の数字は実行を行った順番を示す。
  • 順番によっては正常に作動しない場合もあるため最後は左上の欄から"Kernel > Restart & Run All"をクリック

Filter with python

filtfiltを用いたバンドパスフィルタ(バターワースフィルタ)の記述例

#バターワースフィルタ(バンドパス)

fp = np.array([25, 50])       #通過域端周波数[Hz]
fs = np.array([10, 100])       #阻止域端周波数[Hz]
gpass = 3       #通過域端最大損失[dB]
gstop = 40      #阻止域端最小損失[dB]

def bandpass(x, samplerate, fp, fs, gpass, gstop):#samplerate がサンプリング周波数
    fn = samplerate / 2                           #ナイキスト周波数
    wp = fp / fn                                  #ナイキスト周波数で通過域端周波数を正規化
    ws = fs / fn                                  #ナイキスト周波数で阻止域端周波数を正規化
    N, Wn = signal.buttord(wp, ws, gpass, gstop)  #オーダーとバターワースの正規化周波数を計算
    b, a = signal.butter(N, Wn, 'bandpass')            #フィルタ伝達関数の分子と分母を計算
    y = signal.filtfilt(b, a, x)                  #信号に対してフィルタをかける
    return y                                      #フィルタ後の信号を返す


y = bandpass(f_biceps, samplerate, fp, fs, gpass, gstop)

scipy.signal.filtfilt

scipyのfiltfiltを使用する場合は以下のようにインポートする

from scipy import signal
import matplotlib.pyplot as plt

※pltはインポートしなくても大丈夫?

filtfiltの記述の仕方

filtfiltでバターワースフィルターをかける場合には以下のように記述する

b, a = signal.butter(8, 0.125)
y = signal.filtfilt(b, a, x, padlen=150)

filtfiltのパラメータと返り値

scipy.signal.filtfilt(b, a, x, axis=- 1, padtype='odd', padlen=None, method='pad', irlen=None)`
  1. parameters

    • b : (N,)arrau_like フィルターの分子係数

    • a : (N,)array_like フィルターの分母係数

      a[0]が1でなければaもbもa[0]で正規化される。

    • x : array_like フィルターをかける配列のデータ

    • axis : int, optional フィルターを適用するx軸。デフォルトは-1

    • padtype

    • pandlen

    • method

    • irlen

  2. return

    • ndarray xと同じ形状の(?)フィルタリングされた出力

バターワースデジタルフィルター、バターワースアナログフィルターの設計

バターワースフィルターの設計ではscipy.signal.butterモジュールを使用する。 このモジュールでは N 次元のデジタル、またはアナログバターワースフィルターを設計し、係数を返す。

記述方法

from scipy import signal
import matplotlib.pyplot as plt
b, a = signal.butter(4, 100, 'low', analog=True)

パラメータと返り値

scipy.signal.butter(N, Wn, btype='low', analog=False, output='ba', fs=None)
  1. parameters

    • N : int フィルターの次数 ← buttorモジュールで必要な最低次数を求められる(?)

    • Wn : array_like 臨界周波数。

      ローパス、ハイパスフィルターでは、Wn はスカラー。バンドパス、バンドストップフィルターでは長さ2の配列。

      バターワースフィルターでは、ゲインが通過帯域の1/√2 まで低下する点(「-3dB点」)を表す。

      アナログフィルターでは Wn は各周波数(例:rad/s)

    • btype : {‘lowpass’, ‘highpass’, ‘bandpass’, ‘bandstop’}, optional filterのタイプ。デフォルトはlowpass

    • analog

    • output

    • fs

  2. Returns

    • b, a : nadarray, ndarray IIR フィルターの分子 (b) および 分母 (a) 多項式。 output=‘ba’ のときだけ返される。

    • z, p, k

    • sos

バターワースフィルターの次数選択

バターワースフィルターの次数選択では buttord モジュールを用いる。

このモジュールでは、通過帯域で gpass dB 以上の減衰がなく、停止帯域で gstop dB 以上の減衰がある最低次のデジタルまたはアナログバターワースフィルタの次数を返す。

記述方法

from scipy import signal
import matplotlib.pyplot as pltN, Wn = signal.buttord([20, 50], [14, 60], 3, 40, True)
b, a = signal.butter(N, Wn, 'band', True)
w, h = signal.freqs(b, a, np.logspace(1, 2, 500))

パラメータと返り値

scipy.signal.buttord(wp, ws, gpass, gstop, analog=False, fs=None)
  1. parameters

    • wp, ws : float 通過帯域と阻止帯域のエッジ周波数。

      デジタルフィルタの場合、これらはfsと同じ単位である。デフォルトでは、fsは 2 half-cycles/sample なので、これらは0から1に正規化され、1がナイキスト周波数となる。(wpとwsはhalf-cycles/sample )例えば

            ローパス:wp=0.2, ws=0.3
      
            ハイパス:wp = 0.3, ws = 0.2
      
            バンドパス:wp = [0.2, 0.5]、ws = [0.1, 0.6].
      
            バンドストップ:wp=[0.1,0.6],ws=[0.2,0.5]。
      

      アナログフィルタの場合、wpとwsは角周波数(例:rad/s)です。

    • gpass : float 通過帯域の最大損失(dB)。

    • gstop : float 停止帯域の最小減衰量(dB)。

    • analog : bool, optional

    • fs : float, optional デジタルシステムのサンプリング周波数

  2. returns

    • ord : int 使用を満たすバターワースフィルターの最低次数

    • wn : ndarray or float バターワース固有振動数(すなわち “3dB振動数”)。フィルタリングの結果を得るために、butterと一緒に使用する必要がある。fs が指定された場合、これは同じ単位であり、fs も butter に渡さなければならない。

参考

Create Library

ライブラリの作成方法

  1. directory に __init.py__ ファイルを作成
  2. site-packages ディレクトリに作成したライブラリを追加する(シンボリックリンクでも可)
    • site-packages の場所は
      $ python -m site
      
      で確認できる
    • ディレクトリをパスに追加する場合は次の通り
      $ export PYTHONPATH="<path>:$PYTHONPATH"
      

Anaconda Update

pip のアップデート

pip と setuptools のアップデート

$ python -m pip install --upgrade pip setuptools

-mはインターフェイスオプションで、pythonのモジュール(パッケージ)を実行するために使用

パッケージのアップデート

$ pip install -U <package-name>

または

$ pip install --upgrade <package name>

naconda のアップデート

すべてのパッケージをアップデート

$ conda update --all

特定のパッケージのアップデート

$ conda update <package name1> <package name2>

anaconda 本体のアップデート

$ conda update -n base -c defaults conda

または

$ conda update -n base conda

※上は(base)と作成した仮想環境両方アップデートされた…(下のコマンドは不明)

よく使うオプションは以下の通り

  • -n--name の略で、環境名の指定
  • -c--channel の略で、デフォルトリポジトリだけでなくチャネルを追加で指定

参考

Python Basics

Pythonのプログラムの作成と実行

  • 方法1: C言語のように,テキスト形式でプログラムを書いて実行

    $ vi program.py # プログラム作成
    $ python program.py # プログラム実行
    

    注) Pythonはインタプリタ型言語なのでコンパイルは不要。

  • 方法2: jupyter notebookやIpython等を用いてインタラクティブに実行

コメント

  • #:1行コメント
  • 複数行コメント:“““コメント””” ※ダブルクォートの代わりにシングルを使っても良い →ドックストリング

モジュール・パッケージ・ライブラリ

  • モジュール: クラスや関数を記述したファイル(.py)
  • パッケージ: いくつかのモジュールを一つのディレクトリ(フォルダ)にまとめたもの
  • ライブラリ: いくつかのパッケージをまとめたもの。モジュールやパッケージをライブラリと呼ぶこともある
  1. 標準ライブラリ
  • math: 数学関数モジュール
  • random: 乱数発生モジュール
  1. 外部ライブラリ:追加インストール必要
  • NumPy: 数値計算用の多次元配列ライブラリ。C言語で作られているので高速
  • SciPy: 科学計算ライブラリ
  • pandas: データフレーム(エクセルのような表形式)のデータ解析ライブラリ
  • scikit-learn: 機械学習ライブラリ

モジュールやパッケージ,ライブラリに含まれるオブジェクト(クラスや関数等)を使うには,以下の例のようにimportを用いて読み込みを行う。

Pythonのデータ型について

すべてのPythonオブジェクトはC言語の構造体で定義されており、C言語等の静的型付言語などと比べてオーバーヘッドが生じる

【例】 integer(long)型

struct _longobject{
    long ob_refcnt;
    PyTypeObject ob_type;
    size_t ob_size;
    long ob_digit[1];
};
  • ob_refcnt : Pythonが目盛りの割当と解除を自動的に行うための参照カウンタ
  • ob_type : 変数の方を表すコード
  • ob_size : この後に続くデータの大きさ
  • ob_digit : このPython変数が持つ実際の整数値

PythonリストとNumpy配列

種類 概要
Pytonリスト ポインタ列へのポインタを格納した動的配列。各ポインタは完全なPythonオブジェクトを示すため、柔軟性に利点を持つ一方ですべての変数が同じ方であるケースでは情報が冗長になる。
Numpy配列 すべてのデータの型が同じ固定型の配列のため柔軟性に欠ける一方でデータの保存と操作がはるかに効率的

immutable と mutable

関数の引数(仮引数)の値を関数内で変更した場合,引数が**immutable(変更不可)**な型ならば呼び出した側の引数(実引数)は変化しない。**mutable(変更可能)**ならば,実引数も変化。

  • immutable: int, float, str, tuple
  • mutable: list, dict, set 等(これらについては後述)

immutableな引数については, 返り値を使って更新するようにする。