Python3 ライブラリブック
各種ライブラリの基本的な使用方法

OpenCV / Pillow / pygame / Eel / PyDub / NumPy / matplotlib / SciPy /SymPy / hashlib, passlib / Cython / Numba / ctypes / PyInstaller /JupyterLab / json / urllib / zenhan / jaconv

Copyright © 2017-2022, Katsunori Nakamura

中村勝則
2022 年 3 月 25 日

免責事項
本書の内容は参考的資料であり，掲載したプログラムリストは全て試作品である．本書の使用に伴って発生した不利益，損害の一切の責任を筆者は負わない．

本書におけるサンプルプログラムの実行方法
本書では様々な形で Python スクリプトの実行例を示す．‘〜.py’ の名前を持つファイルとして掲載するサンプルプ
ログラム（Python スクリプト）は次のようにして Python 処理系と共に起動する．
● Windows のコマンドウィンドウで PSF 版 Python を使用する場合

py

スクリプト名.pyEnter● macOS，Linux 環境で PSF 版 Python を使用する場合

python3

スクリプト名.pyEnter● Anaconda Prompt 環境の Python を使用する場合

pythonスクリプト名.py

Enter【Python 対話モードでの実行】

Python 処理系（インタプリタ）に直接 Python の式や文を与える場合は，Python 処理系のプロンプト「>>>」の後に入力する．本書では，対話モードの実行例を示す場合は基本的にこのプロンプト「>>>」も表示する．このような表示の実行例を実際に試みる場合は「>>>」の部分は入力しないこと．

目次
1

画像の入出力と処理

1

1.1

OpenCV . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

1

1.1.1

動画像の入力 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

2

1.1.2

ユーザインターフェース2

1.1.2.13

1.1.3

フレームのファイルへの保存 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

3

1.1.4

静止画像の読込み . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

3

1.1.5

色空間とチャネル . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

4

1.1.5.1

画像フレームのチャネルの順序 . . . . . . . . . . . . . . . . . . . . . . . . . . . .

5

1.1.5.2

色空間の変換 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

6

1.1.5.3

チャネルの分解と合成 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

7

1.1.5.4

色空間の選択に関すること. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

8

1.1.5.5

参考）HSV の色相に関すること . . . . . . . . . . . . . . . . . . . . . . . . . . . .

9

1.1.7

カラー画像からモノクロ画像への変換. . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10

1.1.6.1

モノクロ 2 値化 (1)：一定の閾値で判定 . . . . . . . . . . . . . . . . . . . . . . . .

10

1.1.6.2

モノクロ 2 値化 (2)：閾値を適応的に判定 . . . . . . . . . . . . . . . . . . . . . . .

11

画像フレームに対する描画 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

13

1.1.7.1

基本的な考え方 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

13

1.1.7.2

線分，矢印

1.1.7.3

矩形，円，楕円，円弧 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

14

1.1.7.4

折れ線，多角形 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

16

1.1.7.5

文字列 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

17

1.1.7.6

マーカー . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

18. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13

Pillow . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 20
1.2.1

画像ファイルの読込みと保存 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

1.2.1.1

EPS を読み込む際の解像度 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21

1.2.1.2

画像ファイルの保存 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

21

Image オブジェクトの新規作成 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21

1.2.3

画像の閲覧

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 22

1.2.4

画像の編集

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 22

1.2.4.1

画像の拡大と縮小 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

22

1.2.4.2

画像の部分の取り出し . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

22

1.2.4.3

画像の複製

1.2.4.4

画像の貼り付け . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

1.2.4.5

画像の回転

画像処理

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 23
23

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 23

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 23

1.2.5.1

色の分解と合成 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

23

1.2.5.2

カラー画像からモノクロ画像への変換 . . . . . . . . . . . . . . . . . . . . . . . . .

24

1.2.6

描画 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

25

1.2.7

アニメーション GIF の作成 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

26

1.2.8

Image オブジェクトから画素の数値配列への変換 . . . . . . . . . . . . . . . . . . . . . . . . 27

GUI とマルチメディア
2.1

20

1.2.2

1.2.5

2

動画ファイルからの入力. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

1.1.6

1.2

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

28

pygame . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 28
2.1.1

基礎事項

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 28

2.1.1.1

Surface オブジェクト . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 28

I

2.1.1.2
2.1.2

描画機能

2.1.2.2

回転，拡縮のサンプルプログラム . . . . . . . . . . . . . . . . . . . . . . . . . . .

34

2.1.3

キーボードとマウスのハンドリング . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

36

2.1.4

音声の再生

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 32

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 37

2.1.4.1

Sound オブジェクトを用いる方法 . . . . . . . . . . . . . . . . . . . . . . . . . . . 38

2.1.4.2

Sound オブジェクトから NumPy の配列への変換 . . . . . . . . . . . . . . . . . . . 39

スプライトの利用 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
基礎事項. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 45

2.2.1.1

Chrome の起動モード . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 46

Python/JavaScript で記述した関数の呼出し . . . . . . . . . . . . . . . . . . . . . . . . . . 46関数の戻り値について . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

48

メディアデータの変換： PyDub . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

49

2.3.1

音声ファイルの読込み . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

49

2.3.2

音声データから NumPy の配列への変換

2.3.3

NumPy の配列から音声データへの変換 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 50

2.3.4

音声ファイルの保存 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

2.2.2.1. . . . . . . . . . . . . . . . . . . . . . . . . . . . 49
50

2.3.4.1MP3 形式ファイルとして保存 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 50

2.3.4.2

WAV 形式ファイルとして保存. . . . . . . . . . . . . . . . . . . . . . . . . . . . 50

科学技術系

3.1

40

Eel . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 45

2.2.2

3

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 30
描画のサンプルプログラム

2.2.1

2.3

28

2.1.2.1

2.1.5
2.2

アプリケーションの実行ループ . . . . . . . . . . . . . . . . . . . . . . . . . . . .

51

数値計算と可視化のためのライブラリ：NumPy / matplotlib . . . . . . . . . . . . . . . . . . . . .

51

3.1.1

NumPy で扱うデータ型 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 51

3.1.2

配列オブジェクトの基本的な扱い方 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

51

3.1.2.1

配列の要素の型について

3.1.2.2

真理値の配列 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

52

3.1.2.3

基本的な計算処理 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

53

3.1.2.4

扱える値の範囲 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

54

3.1.2.5

特殊な値：無限大と非数

3.1.2.6

データ列の生成（数列の生成） . . . . . . . . . . . . . . . . . . . . . . . . . . . .

55

3.1.2.7

多次元配列の生成 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

56

3.1.2.8配列の形状の調査 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

56

3.1.2.9

配列の要素へのアクセス. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 52

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 54

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 57

3.1.2.10 スライスにデータ列を与えた場合の動作. . . . . . . . . . . . . . . . . . . . . . . 57

3.1.2.11 指定した行，列へのアクセス . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 58
3.1.2.12 配列形状の変形 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 58
3.1.2.13 行，列の転置 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 60
3.1.2.14 行，列の反転と回転 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 60
3.1.2.15 型の変換 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 61
3.1.2.16 配列の複製（コピー） . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 61
3.1.3

3.1.4

配列の連結と繰り返し . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

62

3.1.3.1

append，concatenate による連結 . . . . . . . . . . . . . . . . . . . . . . . . . . . 62

3.1.3.2

hstack，vstack による連結 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 63

3.1.3.3

tile による配列の繰り返し . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 64

配列への要素の挿入 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

64

行，列の挿入 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

65

3.1.4.1II3.1.5

3.1.6

3.1.7

3.1.8

3.1.9

配列要素の部分的削除 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

66

3.1.5.1

区間を指定した削除 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

66

3.1.5.2

行，列の削除 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

67

配列の次元の拡大 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

67

3.1.6.1

newaxis オブジェクトによる方法 . . . . . . . . . . . . . . . . . . . . . . . . . . . 67

3.1.6.2

expand dims による方法. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 68

データの抽出 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

68

3.1.7.1

真理値列によるマスキング. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 68

3.1.7.2

条件式による要素の抽出. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 69

3.1.7.3

論理演算子による条件式の結合 . . . . . . . . . . . . . . . . . . . . . . . . . . . .

3.1.7.4

where による要素の抽出と置換 . . . . . . . . . . . . . . . . . . . . . . . . . . . . 69

3.1.7.5

最大値，最小値，その位置の探索 . . . . . . . . . . . . . . . . . . . . . . . . . . .

データの整列（ソート）69
70. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 72

3.1.8.1

2 次元配列の整列 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 72

3.1.8.2

整列結果のインデックスを取得する方法. . . . . . . . . . . . . . . . . . . . . . . 73

配列要素の差分の配列 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

3.1.10 配列に対する様々な処理

73. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 74

3.1.10.1 重複する要素の排除 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 74
3.1.10.2 要素の個数の集計 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 74
3.1.10.3 整数要素の集計 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 75
3.1.10.4 指定した条件を満たす要素の集計 . . . . . . . . . . . . . . . . . . . . . . . . . . . 75
3.1.11 配列に対する演算：1 次元から 1 次元 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 75
3.1.12 データの可視化（基本）. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 76

3.1.12.1 作図処理の基本的な手順. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 77

3.1.12.2 2 次元のプロット：折れ線グラフ . . . . . . . . . . . . . . . . . . . . . . . . . . . 77
3.1.12.3 グラフの目盛りの設定 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 80
3.1.12.4 複数のグラフの作成 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 81
3.1.12.5 matplotlib のグラフの構造 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 83
3.1.12.6 グラフの枠を非表示にする方法 . . . . . . . . . . . . . . . . . . . . . . . . . . . . 87
3.1.12.7 極座標プロット . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 87
3.1.12.8 レーダーチャート（極座標の応用） . . . . . . . . . . . . . . . . . . . . . . . . . . 88
3.1.12.9 日本語の見出し・ラベルの表示 . . . . . . . . . . . . . . . . . . . . . . . . . . . . 89
3.1.12.10 グラフを画像ファイルとして保存する方法 . . . . . . . . . . . . . . . . . . . . . . 90
3.1.13 乱数の生成 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 91
3.1.13.1 一様乱数の生成 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 91
3.1.13.2 整数の乱数の生成 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 91
3.1.13.3 正規乱数の生成 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 91
3.1.13.4 乱数の seed について . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 91
3.1.13.5 RandomState オブジェクト . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 92
3.1.14 統計に関する処理 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 93
3.1.14.1 合計 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 93
3.1.14.2 最大値，最小値 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 93
3.1.14.3 平均，分散，標準偏差 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 93
3.1.14.4 分位点，パーセント点 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 94
3.1.14.5 区間と集計（階級と度数調査） . . . . . . . . . . . . . . . . . . . . . . . . . . . . 94
3.1.14.6 最頻値を求める方法 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 97
3.1.14.7 相関係数 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 100
3.1.14.8 データのシャッフル . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 101
III3.1.15 データの可視化（2） . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 101
3.1.15.1 ヒストグラム . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 101
3.1.15.2 散布図 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 103
3.1.15.3 棒グラフ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 103
3.1.15.4 円グラフ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 105
3.1.15.5 箱ひげ図 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 107
3.1.16 多次元配列に対する演算. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 108

3.1.16.1 meshgrid 関数の働き. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 109

3.1.17 データの可視化：3 次元プロット . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 110
3.1.17.1 ワイヤフレーム . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 110
3.1.17.2 面プロット（surface plot） . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 110
3.1.17.3 3 次元の棒グラフ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 112
3.1.17.4 3 次元の散布図 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 112
3.1.18 データの可視化：その他. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 114

3.1.18.1 ヒートマップ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 114
3.1.18.2 表の作成 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 116
3.1.19 高速フーリエ変換（FFT） . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 118
3.1.19.1 時間領域から周波数領域への変換：フーリエ変換 . . . . . . . . . . . . . . . . . . . 118
3.1.19.2 周波数領域から時間領域への変換：フーリエ変逆換 . . . . . . . . . . . . . . . . . . 118
3.1.19.3 プロットのアスペクト比の指定 . . . . . . . . . . . . . . . . . . . . . . . . . . . . 121
3.1.19.4 フーリエ変換を使用する際の注意 . . . . . . . . . . . . . . . . . . . . . . . . . . . 121
3.1.20 複素数の計算 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 122
3.1.20.1 複素数の平方根 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 122
3.1.20.2 複素数のノルム . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 122
3.1.20.3 共役複素数. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 122

3.1.20.4 複素数の偏角（位相） . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 123
3.1.21 行列，ベクトルの計算（線形代数のための計算） . . . . . . . . . . . . . . . . . . . . . . . . 123
3.1.21.1 行列の和と積 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 123
3.1.21.2 単位行列，ゼロ行列，他. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 123

3.1.21.3 行列の要素を全て同じ値にする . . . . . . . . . . . . . . . . . . . . . . . . . . . . 124
3.1.21.4 ベクトルの内積 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 125
3.1.21.5 対角成分，対角行列 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 125
3.1.21.6 行列の転置. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 126

3.1.21.7 行列式と逆行列 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 126
3.1.21.8 固有値と固有ベクトル . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 126
3.1.21.9 行列のランク . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 127
3.1.21.10 複素共役行列 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 127
3.1.21.11 エルミート共役行列 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 127
3.1.21.12 ベクトルのノルム . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 127
3.1.22 入出力：配列オブジェクトのファイル I/O . . . . . . . . . . . . . . . . . . . . . . . . . . . 128
3.1.22.1 テキストファイルへの保存 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 128
3.1.22.2 テキストファイルからの読み込み . . . . . . . . . . . . . . . . . . . . . . . . . . . 130
3.1.22.3 バイナリファイルへの I/O. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 131

3.1.22.4 データの圧縮保存と読み込み . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 132
3.1.22.5 配列をバイトデータに変換して入出力に使用する . . . . . . . . . . . . . . . . . . . 133
3.1.23 行列の検査 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 134
3.1.23.1 全て真，少なくとも 1 つは真：

all，any . . . . . . . . . . . . . . . . . . . . . . 134

3.1.24 配列を処理するユーザ定義関数の実装について . . . . . . . . . . . . . . . . . . . . . . . . . 135
IV3.1.25 行列の計算を応用した計算速度の改善の例 . . . . . . . . . . . . . . . . . . . . . . . . . . . 137
3.1.25.1 要素の型によって異なる計算速度 . . . . . . . . . . . . . . . . . . . . . . . . . . . 138
3.1.26 画像データの扱い . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 138
3.1.26.1 画素の配列から画像データへの変換（PIL ライブラリとの連携） . . . . . . . . . . . 140
3.1.26.2 画像データから画素の配列への変換（PIL ライブラリとの連携） . . . . . . . . . . . 140
3.1.26.3 OpenCV における画素の配列 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 141
3.1.26.4 サンプルプログラム：画像の三色分解 . . . . . . . . . . . . . . . . . . . . . . . . . 142
3.1.27 図形の描画：matplotlib.patches. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 144

3.1.27.1 四角形，円，楕円，正多角形 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 144
3.1.27.2 円弧（楕円弧） . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 145
3.1.27.3 ポリゴン . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 146
3.1.28 3 次元のポリゴン表示 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 146
3.1.29 日付，時刻の扱い . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 148
3.1.29.1 datetime64 クラス . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 148
3.1.29.2 timedelta64 クラス . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 148
3.1.29.3 日付，時刻の応用例 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 149
3.1.30 その他の機能 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 151
3.1.30.1 基準以上／以下のデータの抽出 . . . . . . . . . . . . . . . . . . . . . . . . . . . . 151
3.1.30.2 指定した範囲のデータの抽出 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 153
3.2

科学技術計算用ライブラリ： SciPy . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 155

3.2.1

信号処理ツール: scipy.signal . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 155

3.2.1.1
3.2.2

3.3

基本的な波形の生成 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 155

WAV ファイル入出力ツール: scipy.io.wavﬁle . . . . . . . . . . . . . . . . . . . . . . . . . . 158
3.2.2.1

WAV 形式ファイル出力：

write 関数 . . . . . . . . . . . . . . . . . . . . . . . . 158

3.2.2.2

WAV 形式ファイル入力：

read 関数

3.2.2.3

32-bit ﬂoating-point の WAV 形式サウンドデータ . . . . . . . . . . . . . . . . . . 159. . . . . . . . . . . . . . . . . . . . . . . . 159

数式処理ライブラリ： SymPy . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 161

3.3.1

モジュールの読込みに関する注意 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 161

3.3.2

基礎事項

3.3.3

3.3.4

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 161

3.3.2.1

記号オブジェクトの生成

3.3.2.2

数式の簡単化（評価） . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 162

3.3.2.3

式 f(x,y,...) の構造

3.3.2.4

定数 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 164. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 162（頭部と引数列の取り出し） . . . . . . . . . . . . . . . . 163

基本的な数式処理機能 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 164

3.3.3.1式の展開 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 164

3.3.3.2

因数分解 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 164

3.3.3.3

指定した記号による整理

3.3.3.4

約分：分数の簡単化 (1) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 165

3.3.3.5

部分分数 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 165

3.3.3.6

分数の簡単化 (2)3.3.3.7

代入（記号の置換） . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 166

3.3.3.8

各種の数学関数 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 166

3.3.3.9式の型 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 166. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 164. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 166

解析学的処理 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 167

3.3.4.1

極限 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 167

3.3.4.2

導関数 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 167

3.3.4.3

微分操作の遅延実行 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 168

3.3.4.4

原始関数 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 168

V3.3.5

3.3.6

3.3.4.5

integrate の遅延実行

3.3.4.6

定積分 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 169

3.3.4.7

級数展開 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 169. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 168

各種方程式の求解 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 169

3.3.5.1

代数方程式の求解 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 169

3.3.5.2

微分方程式の求解 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 170

3.3.5.3階差方程式の求解（差分方程式，漸化式） . . . . . . . . . . . . . . . . . . . . . . 170

線形代数. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 171

3.3.6.1

行列の連結. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 171

3.3.6.2

行列の形状. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 172

3.3.6.3

行列の要素へのアクセス

3.3.6.4

行列式 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 173

3.3.6.5

逆行列 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 173

3.3.6.6

行列の転置

3.3.6.7ベクトル，内積 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 173

3.3.6.8固有値，固有ベクトル . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 174. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 172. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 173

3.3.7

総和 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 174

3.3.8

パターンマッチ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 175

3.3.9

数値計算

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 175

3.3.9.1

素因数分解

3.3.9.2

素数 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 176

3.3.9.3

近似値 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 177. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 175

3.3.10 書式の変換出力 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 177
3.3.10.1 LATEX . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 177
3.3.10.2 MathML . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 177
3.3.11 グラフのプロット . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 178
3.3.11.1 グラフを画像ファイルに保存する方法 . . . . . . . . . . . . . . . . . . . . . . . . . 179
4

セキュリティ関連

4.1
4.2

hashlib . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 180
4.1.1

基本的な使用方法 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 180

passlib. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 180

4.2.1
5

180

使用できるアルゴリズム. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 180

プログラムの高速化／アプリケーション構築

5.1

5.2

5.3

Cython . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 182
5.1.1

使用例 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 182

5.1.2

高速化のための調整 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 184

Numba . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 185
5.2.1

基本的な使用方法 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 185

5.2.2

型指定による高速化 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 186

ctypes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 186
5.3.1

C 言語による共有ライブラリ作成の例. . . . . . . . . . . . . . . . . . . . . . . . . . . . . 186

5.3.2

共有ライブラリ内の関数を呼び出す例. . . . . . . . . . . . . . . . . . . . . . . . . . . . . 187

5.3.3

引数と戻り値の扱いについて . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 187

5.3.3.1
5.4

182

配列データの受け渡し . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 190

PyInstaller . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 193
5.4.1

簡単な使用例 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 193

VI

5.4.1.1
6

対話作業環境（JupyterLab）

6.1

195

基礎事項 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 195

6.1.1

起動と終了

6.1.2

表示領域の構成と操作方法 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 196

6.1.3

7

単一の実行ファイルとしてビルドする方法 . . . . . . . . . . . . . . . . . . . . . . 194. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 196

6.1.2.1

ノートブックの使用例 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 197

6.1.2.2

カーネル（Kernel）について . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 199

Notebook での input 関数の実行 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 199

6.2

Markdown によるコメント表示 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 199

6.3

使用例

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 201

6.3.1

MathJax による SymPy の式の整形表示 . . . . . . . . . . . . . . . . . . . . . . . . . . . . 201

6.3.2

IPython.display モジュールによるサウンドの再生 . . . . . . . . . . . . . . . . . . . . . . . 202

その他

7.1

7.2

204

json：データ交換フォーマット JSON の使用 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 204
7.1.1

JSON の表記 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 204

7.1.2

使用例 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 204

7.1.2.1

JSON データのファイル I/O . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 204

7.1.2.2

真理値，None の扱い . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 205

urllib：URL に関する処理 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 206
7.2.1

他バイト文字の扱い（‘%’ エンコーディング） . . . . . . . . . . . . . . . . . . . . . . . . . 206

7.2.1.1

文字コード体系の指定 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 206

7.3

zenhan：全角⇔半角変換 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 207

7.4

jaconv:日本語文字に関する各種の変換 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 207

VII

1

画像の入出力と処理

1.1

OpenCV

OpenCV ライブラリは米インテル社によって開発され，現在は BSD ライセンスで配布されるオープンソースソフ
トウェアである．このライブラリは静止画像，動画像の入出力から画像処理，画像認識，機械学習のための機能を提供する．また，クロスプラットフォームのライブラリであり，インターネットサイト http://opencv.org/ から関連の情報を入手することができる．

OpenCV は独自の UI を実現する機能を備えており，画像の表示や，キーボード，マウスからの入力を受け付ける
ための簡便な機能も提供する．本書では OpenCV に関して導入的な内容について説明するので，更に詳しい事柄に関しては上記の情報サイトなどを参照すること．
このライブラリの使用に先立って，必要なソフトウェアを Python 処理系に予めインストールしておく必要がある．

OpenCV の機能を Python で利用するためのライブラリとして cv2 があり，次のようにして Python 処理系に読み込
む．

import cv2

Python における OpenCV モジュールの利用は，別のモジュール NumPy を前提としており，画像のフレームは
NumPy の ndarray クラス（多次元配列）のオブジェクトとして扱われる．
【サンプルプログラム】
システムに接続されたカメラから画像フレームを入力して，それ（動画）をディスプレイに表示するサンプルプロ
グラム opencv01.py を次に示す．
プログラム：opencv01.py
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

# coding : utf -8# モジュールのインポート
import cv2# 動画像入力の開始
cap0 = cv2 . VideoCapture (0)# フレームレートの取得
fps = cap0 . get ( cv2 . CAP_PROP_FPS )# フレームサイズの取得
w = cap0 . get ( cv2 . C A P _ P R O P _ F R A M E _ WIDTH )h = cap0 . get ( cv2 . C A P _ P R O P _ F R A M E _ H E I G H T )print ( fps , ’( fps ) ’); print (w , ’* ’ , h )# キャプチャと表示
while True :# フレームの読取り( ret , frame ) = cap0 . read ()if ret :# フレームの表示
cv2 . imshow ( ’ Camera : 0 ’ , frame )# キーボードの読取り
k = cv2 . waitKey (1)if k == 27:# ESCなら終了
breakelif k == 67 or k == 99:# ’C ’ ’c ’ な ら 静 止 画 保 存# J P E G の Q u a l i t y は 0 - 100 : 大 き い ほ ど 高 画 質# cv2 . imwrite ( ’ capture . jpg ’ , frame ,[ cv2 . IMWRITE_JPEG_QUALITY ,100])# PNGのQualityは 0 - 9 : 小 さ い 程 高 画 質
cv2 . imwrite ( ’ capture . png ’ , frame ,[ cv2 . IMWRITE_PNG_COMPRESSION ,3])else :
print ( ’ Camera is not ready . ’)break
# 終了処理cap0 . release ()# 動画像入力の開放
cv2 . destroyAllWindows () # ウ ィ ン ド ウ の 消 去

1

このプログラムは，カメラから画像フレームを取得し，それをウィンドウに表示する処理の繰り返しで動画像をリ
アルタイムに表示している．また，毎回の繰り返し処理の中でキーボードの値を取り込み，エスケープボタンが押されたら繰り返し処理を中断する形となっている．動画再生中に「C」のキーを押すと，その瞬間のフレームを静止画として画像ファイルに保存する．

1.1.1

動画像の入力

動画像の入力源はシステムに接続されたカメラもしくは動画ファイルであり，画像フレームは VideoCapture クラスのオブジェクトを介して取得する．動画像の入力処理に先立って，入力元を指定して VideoCapture オブジェクトを生成しておく．
《VideoCapture のコンストラクタ》

VideoCapture(カメラ番号)1)

カメラ番号は 0 から開始する整数であり，システムで最初に認識されるカメラは 0 である．

VideoCapture(動画ファイルのパス)

2)

引数には動画ファイルのパスを文字列として与える．

VideoCapture オブジェクトに対して get メソッドを使用して各種の情報を取得することができる．書き方はVideoCapture オブジェクト.get(属性番号)
属性番号は cv2 のプロパティとして表 1 のように定義されている．
表 1: VideoCapture オブジェクトから得られる値（一部）
属性番号

値

cv2.CAP PROP FPS

フレームレート (fps)

cv2.CAP PROP FRAME WIDTH

フレーム幅

cv2.CAP PROP FRAME HEIGHT

フレーム高さ

動画像の入力処理を終了する場合は，VideoCapture オブジェクトに対して release メソッドを使用する．
動画像の入力は VideoCapture オブジェクトから read メソッドを使用して 1 フレームずつ取り出す．
《フレームのキャプチャ》
書き方：

VideoCapture オブジェクト.read()

メソッド実行後は (実行結果, フレーム) のタプルが返される．実行結果は真理値であり，キャプチャ成功の場
合は True，失敗の場合は False となる．得られるフレームは NumPy の ndarray オブジェクトである．

1.1.2

ユーザインターフェース

cv2 のメソッド imshow を使用して，read メソッドで読み取った画像フレームを表示することができる．
《imshow メソッドによるフレームの表示》
書き方：

cv2.imshow(ウィンドウタイトル, フレーム)

cv2 のメソッド waitKey を使用して，その時点でのキーボードの値を取得することができる．
《waitKey メソッドによるキーボードの値の取得》
書き方：

cv2.waitKey(待ち時間)

待ち時間の単位は ms である．その時点で押されているキーの値（コード）が返される．何も押されていない
場合は 255 が返される．
ユーザインターフェースの使用を終了する場合は，cv2 の destroyAllWindows メソッドを使用する．

2

1.1.2.1

動画ファイルからの入力

動画ファイルからの画像フレームの入力を繰り返すことで，動画の再生が実現できる．次のサンプルプログラム

opencvMovie01.py は，VideoCapture オブジェクトから read メソッドで画像フレームを読み取り，それを imshow メ
ソッドでディスプレイに表示する処理を繰り返すことで動画像の再生を実現している．
プログラム：opencvMovie01.py
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

# coding : utf -8# モジュールのインポート
import cv2# 映像の入力源の取得
cap = cv2 . VideoCapture ( ’ Boy -21827. mp4 ’) # ビ デ オ フ ァ イ ル か ら 入 力
print ( ’ size : ’ ,# フレームサイズの表示( cap . get ( cv2 . C A P _ P R O P _ F R A M E _ W I D T H ) , cap . get ( cv2 . C A P _ P R O P _ F R A M E _ H E I G H T )))while True :( ret , frame ) = cap . read ()# retは画像を取得成功フラグ
if ret :# フレームが得られていれば表示する# フレームのリサイズ
frame = cv2 . resize ( frame , (960 ,540))# フレームを表示する
cv2 . imshow ( ’ Movie Capture ’ , frame )k = cv2 . waitKey (30) # キ ー 入 力 を 3 0 m s e c 待 つ
if k == 27:# ESCキーで終了
breakelse :# フレームが得られていなければ終了する
break# 映像の入力源の開放
cap . release ()cv2 . destroyAllWindows ()1.1.3

フレームのファイルへの保存

cv2 の imwrite メソッドを使用することでフレームを静止画としてファイルに保存することができる．
《imwrite メソッドによるフレームのファイル保存》
書き方：

cv2.imwrite(ファイル名, フレーム, 圧縮指定)

ファイル名は拡張子を付けた文字列で指定する．特に拡張子が .jpg, .png の場合は，それぞれ JPEG,PNG
フォーマットとして圧縮保存ができる．圧縮指定は次の通り．

JPEG:[cv2.IMWRITE JPEG QUALITY, 値]

値は 0〜100 までの整数値で，値が大きい方が高画質（ファイルサイズ大）である．
圧縮指定を省略すると 95 が暗黙値となる．

PNG:[cv2.IMWRITE PNG COMPRESSION, 値]

値は 0〜9 までの整数値で，値が小さい方が高画質（ファイルサイズ大）である．
圧縮指定を省略すると 3 が暗黙値となる．

1.1.4

静止画像の読込み

cv2 の imread メソッドを使用することで，画像ファイルを読み込むことができる．

3

《imread メソッドによる画像ファイルの読込み》
書き方：

cv2.imread(ファイル名, 読込みフラグ)

ファイル名は拡張子を付けた文字列で指定する．読み込みフラグの意味は次の通り．

cv2.IMREAD UNCHANGED ： 画像データをそのまま読み込む（変更なし）
cv2.IMREAD COLOR：

アルファチャンネル（不透明度の指定）を無視する（デフォルト）

cv2.IMREAD GRAYSCALE ： グレースケールに変換して読み込む
読み取った画像をフレームオブジェクト (ndarray) として返す．

静止画像を読み込んで表示するプログラム opencv02.py を次に示す．
プログラム：opencv02.py
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

# coding : utf -8# モジュールのインポート
import cv2# 画像ファイルの読込み
frame = cv2 . imread ( ’ Earth . jpg ’ , cv2 . IMREAD_UNCHANGED )# frame = cv2 . imread ( ’ Earth . jpg ’ , cv2 . IMREAD_COLOR )# frame = cv2 . imread ( ’ Earth . jpg ’ , cv2 . IMREAD_GRAYSCALE )# そのまま# αチャンネル無視# グレースケールに変換# リサイズ
fr2 = cv2 . resize ( frame ,(640 ,640))# 表示
cv2 . imshow ( ’ Camera : 0 ’ , fr2 )# 待ちwhile True :# キーボードの読取り
k = cv2 . waitKey (1)if k == 27:# ESCなら終了
break# 終了処理cv2 . destroyAllWindows () # ウ ィ ン ド ウ の 消 去

このプログラムの 12 行目にあるように，cv2 の resize メソッドを使用することで画像サイズの拡縮ができる．
《resize メソッドによる画像の拡縮》
書き方：

cv2.resize(フレーム, (幅, 高さ) )

引数に与えたフレームを（幅, 高さ）にリサイズしたフレームを返す．

■ フレームのサイズの取得
フレームオブジェクトのプロパティ shape の第 0 番目の要素にはフレームの高さが，第 1 番目の要素にはフレームの横幅が格納されている．
例．フレーム im のサイズの取得>>> im.shape[1], im.shape[0](199, 67)
1.1.5

Enter

←サイズの取得← 199 × 67 のサイズが得られた

色空間とチャネル

色は決まった種類の成分から構成され，それら成分を（色の）チャネルと呼ぶ．色の成分として最も基本的なものに RGB（赤，緑，青）があり，これに基づく色の合成を加法混色（加色混合）1 と呼ぶ．RGB 以外にも色の成分の
1 多くの画像ファイル（画像フォーマット）で採用されている．

4

とり方には各種のものがあり，CMY （シアン，マゼンタ，イエロー）の組み合わせによる色の合成を減法混色（減色混合）2 という．
色の成分（チャネル）と，それらの組み合わせで得られる色の種類の対応を色空間という．

OpenCV を用いてコンピュータビジョンに関する処理を行う場合に多く用いられる色空間を表 2 に示す．
表 2: OpenCV でよく使用される色空間
色空間

解説

RGB

R（赤），G（緑），B（青）のチャネルで構成される最も標準的な色空間．
0 ≤ R ≤ 255，0 ≤ G ≤ 255，0 ≤ B ≤ 255
matplotlib や Pillow などで画像を扱う際にはこの色空間を採用する．

BGR

B（青），G（緑），R（赤）のチャネルで構成される．OpenCV における暗黙の色空間
RGB の逆．

GRAY

モノクロの階調

HSV

H（色相），S（彩度），V（明度）のチャネルで構成される．
0 ≤ H ≤ 180，0 ≤ S ≤ 255，0 ≤ V ≤ 255 （値の範囲は OpenCV 独自のもの）Lab

明度 L と，a，b の補色次元のチャネルで構成される．
（CIE1976 L∗ a∗ b∗ の変種）
0 ≤ L ≤ 255，1 ≤ a ≤ 255，1 ≤ b ≤ 255 （値の範囲は OpenCV 独自のもの）* RGB と BGR は末尾にαチャネル（不透明度）を取ることができる．
* この表に挙げたもの以外にも多くの色空間が OpenCV では扱える．
* 各チャネルの値の範囲は 8 ビットの場合を想定している

1.1.5.1

画像フレームのチャネルの順序

OpenCV の画像フレームでは，画素の色成分の順序（チャネルの順序）が BGR α であり，標準的な RGB α の順序と異なっている．従って，OpenCV の画像フレームを matplotlib 3 などの作図用ライブラリで扱う際には注意が必要である．これに関しては「3.1.26.3 OpenCV における画素の配列」（p.141）でも解説する．
例．チャネルの順序に関する確認>>> import cv2

Enter← OpenCV ライブラリの読込み>>> im = cv2.imread( ’couple.bmp’ )Enter←画像ファイル4 の読込み>>> cv2.imshow( ’couple.bmp’, im )Enter

← OpenCV の機能を用いて画像を表示>>> while True: Enter←キー入力受付サイクル...
k = cv2.waitKey(10)
Enter
...
if k == 27: break
Enter
...
Enter
←キー入力受付サイクルの記述の終了>>> cv2.destroyAllWindows()

Enter←ウィンドウの終了処理

これを実行すると図 1 の (a) のように正常に表示される．

(a) OpenCV の imshow 関数による表示(b) matplotlib の imshow 関数による表示

図 1: 異なるライブラリによる表示の比較
2 プリンタのインクやトナーのための基本的な色の構成．
3 「3.1 数値計算と可視化のためのライブラリ：NumPy / matplotlib」（p.51〜）で解説する．
4 標準画像データベース SIDBA から引用．

5

しかし，次の例のような操作で同じオブジェクト im を matplotlib で表示すると，チャネルの順序が OpenCV と異なることが原因となって図 1 の (b) のように異常な発色となる．
例．matplotlib による画像フレームの表示（先の例の続き）>>> import matplotlib.pyplot as plt← matplotlib ライブラリの読込みEnter>>> plt.imshow( im )Enter
← matplotlib の機能を用いて画像を表示<matplotlib.image.AxesImage object at 0x000001CE791827C8>>>> plt.show()←作図の実行Enter

OpenCV の画像フレームを matplotlib で正しく扱うためには，例えば次のように変換処理を施す必要がある．
例．BGR から RGB への変換（先の例の続き）>>> im2 = im[:,:,[2,1,0]]Enter←チャネルの順序を変更>>> plt.imshow( im2 )Enter← matplotlib の機能を用いて画像を表示<matplotlib.image.AxesImage object at 0x000001CE7BF26488>>>> plt.show()Enter←作図の実行

この処理の結果，図 2 のように（正常に）表示される．

図 2: チャネルの順序を修正後，matplotlib で表示

BGR ⇔ RGB 間の変換は，次に説明する cvtColor でも可能である．
1.1.5.2

色空間の変換cvtColor を使用することで画像データの色空間を変換することができる．
書き方：

cvtColor( 画像フレーム, 変換指定 )引数に与えた「画像フレーム」の色空間を「変換指定」に従って変換したものを返す．例えば，画像の色空間を BGRから RGB に変換するには次のようにする．
例．BGR から RGB への変換（先の例の続き）>>> imRGB = cv2.cvtColor( im, cv2.COLOR BGR2RGB )Enter← BGR から RGB に変換>>> plt.imshow( imRGB )Enter← matplotlib の機能を用いて画像を表示<matplotlib.image.AxesImage object at 0x0000019E75E42F48>>>> plt.show()Enter←作図の実行

この結果，図 2 と同じ結果が表示される．

cvtColor の第 2 引数に与える「変換指定」の一部を表 3 に示す．

▲▲ 注意 ▲▲
OpenCV の利用においては画像フレームの色空間を常に意識すること．
OpenCV における基本的な色空間は BGR である．他のライブラリを併用して画像を取り扱う場合は RGB に変換することも多いので特に注意すること．

6

表 3: cvtColor の引数に与える「変換指定」の値（一部）変換指定
解説（cv2 内での定義）

1.1.5.3

COLOR BGR2RGB
COLOR RGB2BGR

BGR から RGB への変換
RGB から BGR への変換

COLOR BGR2GRAY
COLOR RGB2GRAY

BGR からグレースケールへの変換
RGB からグレースケールへの変換

COLOR GRAY2BGR
COLOR GRAY2RGB

グレースケールから BGR への変換
グレースケールから RGB への変換

COLOR BGR2HSVCOLOR RGB2HSV

BGR から HSV への変換
RGB から HSV への変換

COLOR BGR2LAB
COLOR RGB2LAB

BGR から Lab への変換
RGB から Lab への変換

COLOR HSV2BGRCOLOR HSV2RGB

HSV から BGR への変換
HSV から RGB への変換

COLOR LAB2BGR
COLOR LAB2RGB

Lab から BGR への変換
Lab から RGB への変換

チャネルの分解と合成

画像フレームのチャネルの分解と合成には split, merge を使用する．
《チャネルの分解と合成》
分解：

cv2.split(画像フレーム)引数に与えた「画像フレーム」のチャネルを分解し，(第 1 チャネル, 第 2 チャネル, … ) のタプルを返す．
合成：

cv2.merge( チャネルのタプル )与えた「チャネルのタプル」の順に合成した画像フレームを返す．

画像を読み込んで，分解と再合成をするプログラム opencv03.py を次に示す．
プログラム：opencv03.py
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

# coding : utf -8# モジュールのインポート
import cv2# 画像ファイルの読込み
frame = cv2 . imread ( ’ Earth . jpg ’ , cv2 . IMREAD_UNCHANGED )# リサイズf = cv2 . resize ( frame ,(320 ,320))# 色分解( f_b , f_g , f_r ) = cv2 . split ( f )# 表示
cv2 . imshow ( ’ Red ’ , f_r )cv2 . imshow ( ’ Green ’ , f_g )cv2 . imshow ( ’ Blue ’ , f_b )# 赤の成分
# 緑の成分
# 青の成分

# 再度合成f_bgr = cv2 . merge ( ( f_b , f_g , f_r ) )# 表示
cv2 . imshow (" All " , f_bgr )# 待ちwhile True :# キーボードの読取り

7

28
29
30
31
32
33

k = cv2 . waitKey (1)if k == 27:# ESCなら終了
break# 終了処理cv2 . destroyAllWindows () # ウ ィ ン ド ウ の 消 去

1.1.5.4

色空間の選択に関すること

コンピュータビジョンの分野では，処理の目的に応じて画像の色空間を選択する．ここでは，RGB の画像を HSV，

Lab に変換し，それらの色空間で各チャネルがどのようなものになるかを例示する．
例．サンプル画像の読込みと表示>>> import cv2

Enter← OpenCV ライブラリの読込み>>> import matplotlib.pyplot as plt

Enter← matplotlib ライブラリの読込み>>> imBGR = cv2.imread(’Pepper.bmp’)

Enter←サンプル画像5 の読込みEnter>>> imRGB = cv2.cvtColor( imBGR, cv2.COLOR BGR2RGB )← RGB に変換>>> plt.imshow( imRGB )Enter← matplotlib で画像を表示<matplotlib.image.AxesImage object at 0x00000288FB0F5D88>>>> plt.show()Enter←作図を実行

これにより図 3 の様にサンプル画像が表示される．

図 3: サンプル画像 ’Pepper.bmp’
次に，この画像の色空間を HSV に変換する．
例．HSV に変換し，各チャネルをグレースケールで表示する（先の例の続き）

Enter>>> imHSV = cv2.cvtColor( imBGR, cv2.COLOR BGR2HSV )>>> (imH,imS,imV) = cv2.split( imHSV )Enter← HSV に変換

←各チャネルの取り出し>>> (fig,ax) = plt.subplots( 1,3, figsize=(10,4) )Enter←複数の作図のための設定>>> a1 = ax[0].imshow( imH, cmap=plt.cm.gray )>>> t1 = ax[0].set title(’Hue’)Enter← H チャネルの作図>>> a2 = ax[1].imshow( imS, cmap=plt.cm.gray )>>> t2 = ax[1].set title(’Saturation’)Enter← S チャネルの作図>>> a3 = ax[2].imshow( imV, cmap=plt.cm.gray )Enter← V チャネルの作図>>> t3 = ax[2].set title(’Value’)>>> f = plt.show()Enter←作図を実行

これにより図 4 の様に HSV の各チャネルの画像が表示される．
次に，色空間を Lab に変換する．

5 標準画像データベース SIDBA から引用．

8

H チャネル（色相）S チャネル（彩度）

V チャネル（明度）図 4: HSV に変換した後の各チャネル
例．Lab に変換し，各チャネルをグレースケールで表示する（先の例の続き）

Enter>>> imLab = cv2.cvtColor( imBGR, cv2.COLOR BGR2LAB )>>> (imL,ima,imb) = cv2.split( imLab )← HSV に変換

←各チャネルの取り出しEnter>>> (fig,ax) = plt.subplots( 1,3, figsize=(10,4) )←複数の作図のための設定

Enter>>> a1 = ax[0].imshow( imL, cmap=plt.cm.gray )>>> t1 = ax[0].set title(’L*’)Enter← L チャネルの作図>>> a2 = ax[1].imshow( ima, cmap=plt.cm.gray )>>> t2 = ax[1].set title(’a*’)Enter← a チャネルの作図>>> a3 = ax[2].imshow( imb, cmap=plt.cm.gray )>>> t3 = ax[2].set title(’b*’)Enter← b チャネルの作図>>> plt.show()Enter←作図を実行

これにより図 5 の様に Lab の各チャネルの画像が表示される．

L チャネル（明度）a チャネル（補色次元 1）b チャネル（補色次元 2）

図 5: Lab に変換した後の各チャネル
ここで示した様に，色空間の各チャネルによって際立つものが異なる．このことを応用して，画像から物体を認識する処理などにおいては，色空間と色チャネルを適宜選択する．

1.1.5.5

参考）HSV の色相に関すること

HSV 色空間の色相（H チャネル）を応用すると，画像を構成する画素の「色の種類」を判別することができる．色相は 0 °〜 360 °の円環構造となるが，OpenCV では 0〜180 の範囲の円環構造（図 6）で表現する．

図 6: OpenCV における HSV 空間の色相（H チャネル）
図 6 を描画するためのプログラムを opencv05.py に示す．

9

プログラム：opencv05.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18

# coding : utf -8
import numpy as np
import matplotlib . pyplot as plt
import cv2

1.1.6

カラー画像からモノクロ画像への変換

#
H
S
V

0 〜180 の 色 相 を 図 示 す る た め の 画 像= np . array ([ list ( range (0 ,181))]*20). astype ( ’ uint8 ’)= np . asarray ( [[255]*181]*20 ). astype ( ’ uint8 ’)= np . asarray ( [[255]*181]*20 ). astype ( ’ uint8 ’)# 0 <= H <= 180# 0 〜255# 0 〜255

imHSV = cv2 . merge ( (H ,S , V ) )# 上で作成した各チャネルを合成してimRGB = cv2 . cvtColor ( imHSV , cv2 . COLOR_HSV2RGB )# 表 示 用 に RGBに変換
plt . figure ( figsize =(12 ,2) )plt . imshow ( imRGB )plt . xlim (0 ,180)
plt . yticks ( ticks =[])
plt . show ()cvtColor を用いて，カラー画像をモノクロ画像に変換することができる．
例．カラー画像からモノクロ画像への変換>>> import cv2

Enter← OpenCV ライブラリの読込み>>> import matplotlib.pyplot as plt

Enter← matplotlib ライブラリの読込み>>> im = cv2.imread( ’couple.bmp’ )Enter←画像ファイル6 の読込み>>> imGr = cv2.cvtColor( im, cv2.COLOR BGR2GRAY )Enter←モノクロ画像への変換>>> plt.imshow( imGr, cmap=plt.cm.gray )Enter←画像の表示<matplotlib.image.AxesImage object at 0x000002214219BD08>>>> plt.show()Enter←作図の実行

この処理の結果，図 7 のような画像が表示される．

図 7: カラー画像からモノクロ画像への変換

1.1.6.1

モノクロ 2 値化 (1)：一定の閾値で判定

threshold 関数を使用すると，画像を「白」（255）と「黒」（0）の 2 階調に変換することができる．
書き方 (1)：threshold( 画像フレーム, 閾値, 設定する値, cv2.THRESH BINARY )「閾値」以上の値の画素を「設定する値」に置き換える．また，閾値を自動設定する次のような方法もある．
書き方 (2)：threshold( 画像フレーム, 0, 設定する値, cv2.THRESH OTSU )threshold 関数は，タプル（閾値, 変換後の画像フレーム）を返す．この関数を用いてグレースケール画像を 2 値化する例を示す．
6 標準画像データベース SIDBA から引用．

10

例．グレースケール画像の 2 値化（先の例の続き）>>> (r1, imBW1) = cv2.threshold( imGr, 105, 255, cv2.THRESH BINARY )>>> (r2, imBW2) = cv2.threshold( imGr, 0, 255, cv2.THRESH OTSU )Enter>>> (fig,ax) = plt.subplots( 1,2, figsize=(9,4) )Enter←描画処理の開始>>> a1 = ax[0].imshow( imBW1, cmap=plt.cm.gray )>>> t1 = ax[0].set title(’THRESH BINARY’)

Enter←表示処理 (1)>>> a2 = ax[1].imshow( imBW2, cmap=plt.cm.gray )>>> t2 = ax[1].set title(’THRESH OTSU’)

Enter←表示処理 (2)>>> plt.show()Enter← 2 値化 (1)Enter← 2 値化 (2)←描画の実行

この処理の結果図 8 のような画像が表示される．

(a) cv2.THRESH BINARY による 2 値化(b) cv2.THRESH OTSU による 2 値化

図 8: グレースケールを 2 値化した画像

1.1.6.2

モノクロ 2 値化 (2)：閾値を適応的に判定

またこれらとは別に，adaptiveThreshold 関数を用いる 2 値化の方法もある．
書き方：

adaptiveThreshold( 画像フレーム, 設定する値, 閾値の算出方法,
cv2.THRESH BINARY, 近傍の画素のサイズ, 閾値の調整 )この関数は 2 値化処理の対象の画素の近傍の画素（「近傍の画素のサイズ」の四方）から閾値を自動的に算出し，変換後の画素を 0 にするか「設定する値」にするかを判断する．
「閾値の調整」には，自動的に算出した閾値から更に調整するための値を与える．
「閾値の算出方法」には cv2.ADAPTIVE THRESH GAUSSIAN C や cv2.ADAPTIVE THRESH MEAN Cなどを与える．この関数は変換後の画像フレームを返す．
「近傍の画素のサイズ」を [5, 11, 23] と変えながら画像を 2 値化する例を次に示す．
例．adaptiveThreshold による 2 値化（先の例の続き）>>> (fig,ax) = plt.subplots( 1,3, figsize=(12,4) )>>> for i,n in enumerate([5,11,23]):

Enter←描画処理の開始← for 文による繰り返しの開始

Enter

...
...

imAdpt = cv2.adaptiveThreshold( imGr, 255, cv2.ADAPTIVE THRESH GAUSSIAN C,
cv2.THRESH BINARY, n, 15 )

...
...

a = ax[i].imshow( imAdpt, cmap=plt.cm.gray )t = ax[i].set title(’Block:’+str(n) )

...

Enter

>>> plt.show()← for 文による繰り返しの終了

Enter←描画の実行

この処理の結果，図 9 のような画像が表示される．

11

Enter

←表示処理

(a) 近傍画素数 5(b) 近傍画素数 11(b) 近傍画素数 23

図 9: adaptiveThreshold による 2 値化
影の写り込んだ文書の画像を 2 値化する例を次に示す．
例．影の写り込んだ文書画像の読込み>>> import cv2

Enter← OpenCV の読込み>>> import matplotlib.pyplot as plt← matplotlib の読込みEnter>>> imGr = cv2.imread( ’grscale01.jpg’, cv2.IMREAD GRAYSCALE )Enter←画像の読込み>>> plt.imshow( imGr, cmap=plt.cm.gray )Enter←画像の表示処理<matplotlib.image.AxesImage object at 0x0000029CAEF40E48>>>> plt.show()

Enter←描画の実行

これを実行して画像を表示した例を図 10 の (a) に示す．

(a) 元の画像(b) 2 値化した画像

図 10: 影の写り込んだ文書画像の 2 値化
図 10 の (a) の画像を 2 値化する例を次に示す．
例．閾値の算出方法に cv2.ADAPTIVE THRESH MEAN C を指定する（先の例の続き）>>> imAdpt = cv2.adaptiveThreshold( imGr, 255, cv2.ADAPTIVE THRESH MEAN C,...

cv2.THRESH BINARY, 5, 19 )Enter

← 2 値化の処理>>> plt.imshow( imAdpt, cmap=plt.cm.gray )Enter←画像の表示処理<matplotlib.image.AxesImage object at 0x0000029CAEE1EE08>>>> plt.show()

Enter←描画の実行

この例では近傍のサイズを 5 に（比較的細かく判定），閾値の調整に 19（大雑把に切り落とす）を設定している．この処理の結果，図 10 の (b) のような画像が表示される．

12

1.1.7

画像フレームに対する描画

OpenCV の画像フレームは NumPy の配列オブジェクトであり，配列の要素の書き換えによって描画ができる．これを応用することで，物体認識の処理の結果を元の画像の上に輪郭線や矩形を描く形でデモンストレーションすることができる．あるいは，画像の上に各種の注釈を表示したり，様々な形のマーキングを行うこともできる．

1.1.7.1

基本的な考え方

画像フレームの配列の画素を直接設定することで描画する．これに関して段階を踏んで例示する．
例．白地の画像フレームを作成する>>> import numpy as np

Enter← NumPy の読込み>>> import cv2

Enter← matplotlib の読込みEnter>>> import matplotlib.pyplot as plt← OpenCV の読込み>>> im = np.full( (30,50,3), 255 )←全ての画素が白の画像フレームを作成

Enter>>> plt.imshow( im )Enter
←画像の表示<matplotlib.image.AxesImage object at 0x000001A32C93E488>>>> plt.show()

Enter←描画の実行

この結果，図 11 の (a) ような画像が表示される．

(a) 全ての画素が白の画像(b) 赤い矩形の描画（RGB）

図 11: 画素を直接設定して描画
次に，作成した白い画像フレームの上に赤い矩形を描く処理を示す．
例．画僧フレームに直接 RGB = [255,0,0] の画素を設定する（先の例の続き）>>> im[10:20,20:30] = [255,0,0]Enter←配列の要素に値を設定>>> plt.imshow( im )Enter
←画像の表示<matplotlib.image.AxesImage object at 0x000001A32E91EF08>>>> plt.show()

Enter←描画の実行

この例では配列の 10〜19 の行範囲，20〜29 の列範囲の画素に直接「赤」を意味する値を設定している．この結果，図11 の (b) ような画像が表示される．
注意）上に示した例は RGB 色空間によるものである．
これを応用した各種図形の描画や文字列の描画のための機能が OpenCV には備わっている．次に，それらに関して解説する．

1.1.7.2

線分，矢印

line 関数で画像フレームに線分を書き込むことができる．
書き方：

line( 画像フレーム, 始点, 終点, 画素, thickness=太さ, lineType=描画手法 )描画対象の「画像フレーム」に「太さ」の線分を描く．
「始点」「終点」は (横位置, 縦位置) の形で，「画素」には線分を構成する画素の色成分を (チャネル 1, チャネル 2,…) の形で与える．
「描画手法」には cv2.LINE AA を指定することが推奨されている．この関数は与えた「画像フレーム」を直接変更し，それを返す．

arrowedLine 関数で画像フレームに矢印を書き込むことができる．
書き方：

arrowedLine( 画像フレーム, 始点, 終点, 画素, thickness=太さ, tipLength=矢の長さ )13描画対象の「画像フレーム」に「太さ」の矢印を描く．
「始点」
「終点」
「画素」に関しては line 関数の場合と同様である．矢印の矢の部分は終点に現れ，その長さは「矢の長さ」で与える．また「矢の長さ」は矢印全体の長さに対する比率で与える．
例．線分と矢印の描画（cv2,plt は読込み済みであるとする）

Enter>>> imRGB = np.full( (360,640,3), 255 )←白の画素の配列を作成>>> im = cv2.line( imRGB, (30,20), (610,20), (255,0,0),
Enter
...
thickness=2, lineType=cv2.LINE AA )Enter

←赤い線分の描画>>> im = cv2.line( imRGB, (30,45), (610,45), (0,255,0),
Enter
...
thickness=8, lineType=cv2.LINE AA )Enter

←緑の線分の描画>>> im = cv2.line( imRGB, (30,90), (610,90), (0,0,255),
Enter
...
thickness=32, lineType=cv2.LINE AA )Enter

←青の線分の描画>>> im = cv2.arrowedLine( imRGB, (30,135), (610,135), (0,255,255),
Enter
...
thickness=2, tipLength=0.03 )Enter←シアンの矢印の描画>>> im = cv2.arrowedLine( imRGB, (30,200), (610,200), (255,0,255),
Enter
...
thickness=8, tipLength=0.07 )Enter←マゼンタの矢印の描画>>> im = cv2.arrowedLine( imRGB, (30,300), (610,300), (255,255,0),
Enter
...
thickness=32, tipLength=0.1 )Enter←黄色の矢印の描画>>> f1 = plt.imshow( imRGB )>>> plt.show()

Enter

Enter

←画像の表示←描画の実行

この結果，図 12 のような画像フレームが表示される．

図 12: 線分と矢印の描画

1.1.7.3

矩形，円，楕円，円弧

rectangle 関数で画像フレームに矩形を書き込むことができる．
書き方：

rectangle( 画像フレーム, 始点, 終点, 画素, thickness=太さ, lineType=描画手法 )「始点」「終点」を対角線とする「太さ」の矩形を描く．
「太さ」に負の値を与えると，矩形を塗りつぶす．
「画素」「描画手法」に関しては line 関数の場合と同様である．
例．矩形の描画（cv2,plt は読込み済みであるとする）>>> imRGB = np.full( (150,410,3), 255 )Enter←白の画素の配列を作成>>> im = cv2.rectangle( imRGB, (10,10), (50,140), (255,0,0),
Enter
...
thickness=2, lineType=cv2.LINE AA )Enter

←赤い矩形の描画>>> im = cv2.rectangle( imRGB, (60,10), (120,140), (0,255,0),
Enter
...
thickness=8, lineType=cv2.LINE AA )Enter

←緑の矩形の描画>>> im = cv2.rectangle( imRGB, (150,25), (250,125), (0,0,255),
Enter
...
thickness=32, lineType=cv2.LINE AA )Enter

←青の矩形の描画>>> im = cv2.rectangle( imRGB, (280,10), (400,140), (255,255,0),
Enter
...
thickness=-1, lineType=cv2.LINE AA ) Enter ←黄色の矩形（塗りつぶし）の描画>>> f1 = plt.imshow( imRGB )>>> plt.show()

Enter

Enter

←画像の表示←描画の実行14

この結果，図 13 のような画像フレームが表示される．

図 13: 矩形の描画

circle 関数で画像フレームに円を書き込むことができる．
書き方：

circle( 画像フレーム, 中心, 半径, 画素, thickness=太さ, lineType=描画手法 )「中心」の位置に「半径」の円を「太さ」で描く．
「太さ」に負の値を与えると，円を塗りつぶす．
「画素」「描画手法」
に関しては line 関数などの場合と同様である．
例．円の描画（cv2,plt は読込み済みであるとする）

Enter>>> imRGB = np.full( (100,200,3), 255 )←白の画素の配列を作成>>> im = cv2.circle( imRGB, (50,50), 45, (255,0,0),
Enter
...
thickness=5, lineType=cv2.LINE AA )Enter

←赤い円の描画>>> im = cv2.circle( imRGB, (150,50), 48, (0,0,255),
Enter
...
thickness=-1, lineType=cv2.LINE AA )Enter

←青い円の描画>>> f1 = plt.imshow( imRGB )>>> plt.show()Enter←画像の表示Enter←描画の実行

この結果，図 14 のような画像フレームが表示される．

図 14: 円の描画

ellipse 関数で画像フレームに楕円を書き込むことができる．
書き方 (1)：ellipse( 画像フレーム, (中心, (横幅, 高さ), 傾斜角度), 画素,
thickness=太さ, lineType=描画手法 )「中心」の位置に「横幅」「高さ」の楕円を「太さ」で描く．
「傾斜角度」には時計回りの角度（ °）を与える．
「太さ」に負の値を与えると，楕円を塗りつぶす．
「画素」「描画手法」に関しては line 関数などの場合と同様である．
例．楕円の描画（cv2,plt は読込み済みであるとする）>>> imRGB = np.full( (100,200,3), 255 )Enter←白の画素の配列を作成>>> im = cv2.ellipse( imRGB, ((50,50), (90,50), 0), (255,0,0),
Enter
...
thickness=4, lineType=cv2.LINE AA )Enter
←赤い楕円の描画>>> im = cv2.ellipse( imRGB, ((100,50), (90,50), 60), (0,255,0),
Enter
...
thickness=4, lineType=cv2.LINE AA )Enter
←緑の楕円の描画>>> im = cv2.ellipse( imRGB, ((150,50), (90,50), 0), (0,0,255),
Enter
...
thickness=-1, lineType=cv2.LINE AA )Enter
←青い楕円の描画>>> f1 = plt.imshow( imRGB )>>> plt.show()

Enter

Enter

←画像の表示←描画の実行15

この結果，図 15 のような画像フレームが表示される．

図 15: 楕円の描画

ellipse 関数は画像フレームに円弧（楕円弧）を書き込むこともできる．
（先の場合とは引数の与え方が異なる）
書き方 (2)：

ellipse( 画像フレーム, 中心, (横幅, 高さ), 傾斜角度, 開始角度, 終了角度, 画素,
thickness=太さ, lineType=描画手法 )「中心」の位置に，円弧（楕円弧）の元になる楕円を「横幅」「高さ」「太さ」で想定し，「開始角度」から「終了角度」
までの範囲の弧を描く．角度は時計回りで単位は「 °」である．他の引数に関しては先の書き方 (1) に準じる．
例．楕円弧の描画（cv2,plt は読込み済みであるとする）>>> imRGB = np.full( (80,270,3), 255 )Enter←白の画素の配列を作成>>> im = cv2.ellipse( imRGB, (55,40), (50,30), 0,
Enter
...
30, 240, (255,0,0),
Enter
...
thickness=4, lineType=cv2.LINE AA )Enter

←赤い楕円弧の描画>>> im = cv2.ellipse( imRGB, (150,40), (50,30), 0,
Enter
...
120, 330, (0,255,0),
Enter
...
thickness=4, lineType=cv2.LINE AA )Enter

←緑の楕円弧の描画>>> im = cv2.ellipse( imRGB, (232,40), (50,30), -30,
Enter
...
120, 330, (0,0,255),
Enter
...
thickness=4, lineType=cv2.LINE AA )Enter

←青い楕円弧の描画>>> f1 = plt.imshow( imRGB )>>> plt.show()Enter←画像の表示Enter←描画の実行

この結果，図 16 のような画像フレームが表示される．

図 16: 楕円弧の描画

1.1.7.4

折れ線，多角形

polylines 関数で画像フレームに折れ線を書き込むことができる．
書き方：

polylines( 画像フレーム, [座標データ], クローズ選択, 画素,
thickness=太さ, lineType=描画手法 )「座標データ」は [[x1,y1], [x2,y2],…, [xn,yn]] の形の配列であり，描く折れ線の始点，コーナー，終点の座標を保持する．
「クローズ選択」に True を与えると始点と終点を結ひ，False を与えると始点と終点が開いた折れ線となる．
「画素」「太さ」「描画手法」に関しては line 関数などの場合と同様である．

ﬁllPoly 関数で画像フレームに塗りつぶしの折れ線を書き込むことができる．
書き方：

ﬁllPoly( 画像フレーム, [座標データ], 画素 )「座標データ」については polylines に準じる．

16

例．各種の折れ線の描画（cv2,plt は読込み済みであるとする）>>> imRGB = np.full( (90,150,3), 255 )Enter←白の画素の配列を作成>>> pl1 = np.array([[10,40],[10,10],[40,40],[40,10],[70,40]]) Enter ←折れ線 1 の座標データ>>> im = cv2.polylines( imRGB, [pl1], False, (255,0,0),
Enter
...
thickness=4, lineType=cv2.LINE AA )Enter

←折れ線 1 の描画>>> pl2 = np.array([[10,50],[10,80],[40,50],[40,80],[70,50]]) Enter ←折れ線 2 の座標データ>>> im = cv2.polylines( imRGB, [pl2], True, (0,0,255),
Enter
...
thickness=4, lineType=cv2.LINE AA )Enter

←折れ線 2 の描画>>> pl3 = np.array([[80,20],[110,40],[110,20],[140,45],
Enter
...
[110,70],[110,50],[80,70]])Enter←折れ線 3 の座標データ
Enter>>> im = cv2.fillPoly( imRGB, [pl3], (0,255,0) )>>> f1 = plt.imshow( imRGB )>>> plt.show()Enter←折れ線 2 の描画←画像の表示Enter←描画の実行

この結果，図 17 のような画像フレームが表示される．

図 17: 折れ線の描画

ﬁllConvexPoly 関数で画像フレームに塗りつぶしの多角形（凸）を書き込むことができる．
書き方：

ﬁllConvexPoly( 画像フレーム, 座標データ, 画素 )引数については ﬁllPoly に準じる．
例．多角形の描画（cv2,plt は読込み済みであるとする）

Enter>>> imRGB = np.full( (100,120,3), 255 )←白の画素の配列を作成>>> pl1 = np.array([[60,10],[110,35],[110,65],...
[60,90],[10,65],[10,35]]) Enter ←多角形の頂点の座標データ>>> im = cv2.fillConvexPoly( imRGB, pl1, (255,0,255) )>>> f1 = plt.imshow( imRGB )>>> plt.show()

Enter

Enter

Enter

←多角形の描画←画像の表示←描画の実行

この結果，図 18 のような画像フレームが表示される．

1.1.7.5

文字列

putText 関数で画像フレームに文字列を書き込むことができる．
書き方：

putText( 画像フレーム, 文字列, 位置, フォント, 比率, 画素,
thickness=太さ, lineType=描画手法 )「位置」に「文字列」を表示する．
「比率」には文字の標準の大きさに対する比率を与える．
「画素」
「太さ」
「描画手法」
に関しては line 関数などの場合と同様である．
「フォント」に指定できるものを表 4 に挙げる．
表 4 に挙げたフォントで文字列を描画する例を示す．

17

図 18: 多角形（凸）の描画
表 4: putText 関数に与えるフォント（一部）

FONT HERSHEY SIMPLEX

FONT HERSHEY COMPLEX

FONT HERSHEY PLAIN

FONT HERSHEY DUPLEXFONT HERSHEY TRIPLEXFONT HERSHEY SCRIPT SIMPLEX

FONT HERSHEY SCRIPT COMPLEX
例．文字列の描画（cv2,plt は読込み済みであるとする）←白の画素の配列を作成

Enter>>> imRGB = np.full( (240,540,3), 255 )>>> im = cv2.putText( imRGB, ’simplex SIMPLEX’, (15, 35),Enter
←文字列 1 の描画...
cv2.FONT HERSHEY SIMPLEX, 1.0, (255,0,0), thickness=1)>>> im = cv2.putText( imRGB, ’complex COMPLEX’, (15, 65),
Enter
←文字列 2 の描画...
cv2.FONT HERSHEY COMPLEX, 1.0, (0,255,0), thickness=1)>>> im = cv2.putText( imRGB, ’plain PLAIN x2.0’, (15, 100),
Enter←文字列 3 の描画...
cv2.FONT HERSHEY PLAIN, 2.0, (0,0,255), thickness=1)>>> im = cv2.putText( imRGB, ’duplex DUPLEX’, (15, 130),Enter←文字列 4 の描画...
cv2.FONT HERSHEY DUPLEX, 1.0, (0,255,255), thickness=1)>>> im = cv2.putText( imRGB, ’triplex TRIPLEX’, (15, 160),
Enter←文字列 5 の描画...
cv2.FONT HERSHEY TRIPLEX, 1.0, (255,0,255), thickness=1)>>> im = cv2.putText( imRGB, ’script simplex SCRIPT SIMPLEX’, (15, 190), Enter ←文字列 6 の描画...
cv2.FONT HERSHEY SCRIPT SIMPLEX, 1.0, (0,0,0), thickness=1)>>> im = cv2.putText( imRGB, ’script complex SCRIPT COMPLEX’, (15, 220), Enter ←文字列 7 の描画...
cv2.FONT HERSHEY SCRIPT COMPLEX, 1.0, (0,0,0), thickness=1)>>> f1 = plt.figure( figsize=(8,4) )>>> f2 = plt.imshow( imRGB )>>> plt.show()

Enter

Enter

Enter

←画像サイズの設定←画像の表示←描画の実行

この結果，図 19 のような画像フレームが表示される．

(a) thickness=1 の場合(b) thickness=2 の場合

図 19: 文字列の描画（thickness の値で太さを調整できる）

1.1.7.6

マーカー

drawMarker 関数で画像フレームにマーカーを書き込むことができる．

18

書き方：

drawMarker( 画像フレーム, 位置, 画素, マーカーの種類,
thickness=太さ, lineType=描画手法 )「位置」に「マーカーの種類」で指定したマーカーを表示する．
「画素」
「太さ」
「描画手法」に関しては line 関数などの場合と同様である．
「マーカーの種類」に指定できるものを表 5 に挙げる．
表 5: drawMarker 関数で表示できるマーカー
マーカーの種類
表示 マーカーの種類

表示

MARKER CROSS＋MARKER TILTED CROSS×

MARKER STAR＊

MARKER DIAMOND◇

MARKER SQUARE□MARKER TRIANGLE UP△

MARKER TRIANGLE DOWN▽

表 5 に挙げたマーカーを描画する例を示す．
例．マーカーの描画（cv2,plt は読込み済みであるとする）

Enter>>> imRGB = np.full( (100,190,3), 127 )←グレーの画素の配列を作成>>> im = cv2.drawMarker( imRGB, (30,25), (255,0,0),...
markerType=cv2.MARKER CROSS, markerSize=20,...
thickness=1, line type=cv2.LINE AA )←「＋」の描画Enter>>> im = cv2.drawMarker( imRGB, (70,25), (0,255,0),...
markerType=cv2.MARKER TILTED CROSS, markerSize=20,...
thickness=1, line type=cv2.LINE AA )Enter>>> im = cv2.drawMarker( imRGB, (110,25), (0,0,255),...
markerType=cv2.MARKER STAR, markerSize=20,...
thickness=1, line type=cv2.LINE AA )←「＊」の描画

Enter←「×」の描画>>> im = cv2.drawMarker( imRGB, (150,25), (0,255,255),...
markerType=cv2.MARKER DIAMOND, markerSize=20,...
thickness=1, line type=cv2.LINE AA )Enter←「◇」の描画>>> im = cv2.drawMarker( imRGB, (30,65), (255,0,255),...
markerType=cv2.MARKER SQUARE, markerSize=20,...
thickness=1, line type=cv2.LINE AA )Enter←「□」の描画>>> im = cv2.drawMarker( imRGB, (70,65), (255,255,0),...
markerType=cv2.MARKER TRIANGLE UP, markerSize=20,...
thickness=1, line type=cv2.LINE AA )>>> im = cv2.drawMarker( imRGB, (110,65), (255,255,255),...
markerType=cv2.MARKER TRIANGLE DOWN, markerSize=20,...
thickness=1, line type=cv2.LINE AA )>>> f1 = plt.imshow( imRGB )>>> plt.show()

Enter

Enter

Enter

←「△」の描画

Enter←画像の表示←描画の実行

この結果，図 20 のような画像フレームが表示される．

(a) thickness=1 の場合(b) thickness=2 の場合

図 20: マーカーの描画（thickness の値で太さを調整できる）

19←「▽」の描画

1.2

Pillow

Pillow は Python で静止画像を処理するためのモジュールである．本書では Pillow に関する導入的な内容について説明する．更に詳しい事柄に関しては，インターネットサイト https://pillow.readthedocs.io/ をはじめとする情報源を参照すること．
このモジュールの使用に先立って，必要なソフトウェアを Python 処理系にインストールしておく必要がある．実際に使用する場合は，次のようにして必要なサブモジュールを Python 処理系に読み込む．

Pillow のサブモジュール

from PIL import
1.2.1

画像ファイルの読込みと保存

画像ファイルを読み込むには，Image モジュールのメソッド open を使用する．
例．画像ファイル test01.jpg の読込み．
← Image モジュールの読込みEnter>>> from PIL import Image>>> im = Image.open(’test01.jpg’,’r’)Enter←画像ファイルの読み込み＜画像ファイルの読込み＞
書き方：

Image.open(ファイル名, モード)

モードの指定は省略可能であるが，指定するばあいは ’r’ を与える．この結果，画像データが Image オブジェ
クトとして返される．ファイル名（パス名）は拡張子を伴う文字列で与える．

Pillow のバージョンが 4.1 の場合に読み書きがサポートされている画像フォーマットは次の通りである．
BMP

EPS

GIF

ICNS

ICO

IM

JPEG

JPEG 2000

MSP

PCX

PNG

PPM

SGI

SPIDER

TIFF

WebP

XBM

Image オブジェクトに対して各種の編集や処理を行うことができる．ファイルから読み込んだ Image オブジェクトには size，format，mode ， といったプロパティがあり，それぞれ画素サイズ（横縦各成分のタプル），画像フォー
マット，画像モードの情報が保持されている．また info プロパティには辞書型オブジェクトとして各種情報が保持されている．
画像の各種プロパティの調査>>> from PIL import Image>>> im = Image.open(’Earth.jpg’)>>> type( im )Enter

←パッケージの読込み

Enter
Enter

←画像ファイルの読込み←取得したデータの型を調べる<class ’PIL.JpegImagePlugin.JpegImageFile’> ← Pillow 独自のデータ型>>> im.size←画素サイズの調査

Enter←画素サイズ(2048, 2048)>>> im.format←画像フォーマット’JPEG’>>> im.mode←画像モードの調査

Enter

’RGB’
>>> im.info[’dpi’](300, 300)

←画像フォーマットの調査

Enter←画像モードEnter←画像解像度の調査←画像解像度

画像モードは色成分の構成を意味するもので，表 6 のような種類がある．

info プロパティの中には ’dpi’ というキーワードがあり，対象画像の解像度の値が保持されている．

20

画像モード

表 6: 画像モード
画像モード 色成分の構成

色成分の構成’1’（数字） 白黒 2 値’L’

8 ビットグレースケール’RGB’

24 ビットカラー’RGBA’

24 ビットカラー＋α値（8 ビット）

’CMYK’

減色混合カラー（32 ビット）

’HSV’

HSV 色空間表現によるカラー（24 ビット）
※ 各色の成分のことをバンド（band）と呼ぶ

1.2.1.1

EPS を読み込む際の解像度

EPS（Encapsulated PostScript）はベクトル図形であり，Image オブジェクトとして読み込む際にラスタライズ7 される．このときの解像度は暗黙で 72dpi 程度（標準的なディスプレイの解像度）となっている．更に高い解像度で EPSを読み込むには，open で EPS ファイルを読み込んだ直後に，得られた Image オブジェクトに対して load メソッドを実行する．この際に，キーワード引数 ‘scale=倍率’ を与えてることで，暗黙の解像度に対する「倍率」を適用した
形で再度ライタライズされる．
（次の例を参照のこと）
例．EPS ファイル ‘pic01.eps’ を 4 倍の解像度でラスタライズする

im = Image.open(’pic01.eps’)←’pic01.eps’ を暗黙の解像度で一旦読み込む

im.load(scale=4)← 4 倍の解像度で再度ラスタライズ

1.2.1.2

画像ファイルの保存

Image オブジェクトは save メソッドを使用することでファイルに保存することができる．
＜画像のファイルへの保存＞
書き方：

Image オブジェクト.save(ファイル名, オプション)

この結果 Image オブジェクトがファイルに保存される．ファイル名（パス名）は拡張子を伴う文字列で与える．

本書では特に圧縮形式のフォーマットとして JPEG, PNG の利用頻度が高いと考え，これらのフォーマットで保存する場合のオプションについて説明する．

フォーマット

表 7: 画像ファイルを保存する際のオプション（一部）キーワード引数意味

JPEG

quality=整数値

画質の指定．1〜95 の値で値が大きいほど高画質．
デフォルトは 75

dpi=(x,y)

横方向，縦方向それぞれの解像度

compress level=整数値

圧縮率の指定．0〜9 の値で値が小さいほど高画質．
デフォルトは 6

dpi=整数値

画像の解像度PNG

1.2.2

Image オブジェクトの新規作成

Image モジュールの new メソッドを使用することで，Image オブジェクトを新規に作成することができる．
＜ Image オブジェクトの作成＞
書き方：

Image.new(モード, サイズ, 初期ピクセル値)

初期ピクセル値： 生成した直後に全ての画素に与える初期値
モードが ’1’ の場合は 0（黒）か 1（白），’L’ の場合は 0（黒）〜255（白），その他のモードでは各成分 0〜255 のタプル．

7 ラスタライズ：画素に展開すること．

21

新規に作成した Image オブジェクト上に描画したり，他の Image オブジェクトを配置（複写）することができる．

1.2.3

画像の閲覧

Image オブジェクトに対して show メソッドを使用すると，OS に設定されている画像ビューワが起動して当該オブジェクトの内容を表示することができる．
例．Image オブジェクト im の表示

im.show()
この結果，画像ビューワが起動して im の内容が表示される．画像ビューワが開いている間は show メソッド実行部分
で当該スレッドがブロックし，画像ビューワが終了するのを待つ．
このメソッドを使用するには，Python 処理系を実行する OS において，使用する画像ビューワの設定をしておく必
要がある．

1.2.4

画像の編集

ここでは，Image オブジェクトを加工する方法について説明する．

1.2.4.1

画像の拡大と縮小

resize メソッドを使用することで Image オブジェクトの画素サイズを変更することができる．
例．Image オブジェクトの画素サイズ変更

im2 = im1.resize( (300,300) )これは Image オブジェクト im1 を 300 × 300 の画素サイズにして，それを im2 としている例である．
画像の画素サイズを変更すると，画素が乱れて画質が劣化することが多いが resize メソッドを実行する際に，画質の劣化を軽減するための各種のフィルタ（表 8）を指定することができる．
リサイズにおけるフィルタ指定の例

im2 = im1.resize( (300,300), resample=Image.LANCZOS )表 8: 各種フィルタ
フィルタ

効果

Image.NEAREST

画素の補間に近傍の画素を使用する（デフォルト）

Image.BOX

画素の補間にボックス近似を使用する

Image.BILINEAR

画素の補間に線形近似を使用する

Image.HAMMING

線形近似より若干鮮明な補間処理

Image.BICUBIC

画素の補間に 3 次補間を使用する

Image.LANCZOS

Lanczos フィルタによる補間処理

フィルタ選択の判断は扱う画像によって異なるので実際に実行して目視確認するのが良い．
参考）画素サイズ変更には thumbnail メソッドも使用できる．thumbnail メソッドは対象オブジェクト
そのものを変更する．

1.2.4.2

画像の部分の取り出し

crop メソッドを使用すると，Image オブジェクトから矩形領域を取り出すことができる．Image オブジェクト imから部分を取り出す場合，取り出したい矩形領域の左上の座標を (Ux , Uy )，右下の座標を (Lx , Ly ) とするとき次のようにする.

im2 = im.crop( (Ux,Uy,Lx,Ly) )この結果，指定した矩形領域が Image オブジェクト im2 として得られる．

22

画像の複製

1.2.4.3

Image オブジェクトの複製を作成するには copy メソッドを使用する．
複製の例．Image オブジェクト im の複製 im2 を作成する

im2 = im.copy()
画像の貼り付け

1.2.4.4

Image オブジェクトの上に別の Image オブジェクトを貼り付ける（複写する）には paste メソッドを使用する．貼り付けられる Image オブジェクトを im1, 貼り付ける Image オブジェクトを im2 とする場合，im1 上の貼り付ける位
置を (Px , Py ) とすると，次のように記述して実行する．
書き方：

im1.paste(im2,(Px,Py))

この結果，im1 上の (Px , Py ) の位置に im2 の内容が貼り付けられる．
（im1 自体が変更される）
画像の回転

1.2.4.5

Image オブジェクトを回転させたものを得るには rotate メソッドを使用する．
書き方：

Image オブジェクト.rotate(角度)引数に与える角度の単位は「度」である．この処理によって，回転された結果の Image オブジェクトが返される．
回転の結果，元の画像が Image オブジェクトの画素サイズに収まらずに切れてしまうことがある．その場合は rotate
メソッドの引数にキーワード引数 expand=True を与えると，回転後に画像が収まるように結果の Image オブジェク
トの画素サイズが拡大される．また，回転処理によって画素が乱れることがあるが，キーワード引数 resample=フィ
ルタ を与えることで乱れを軽減することができる．フィルタは基本的には表 8 に挙げたものが指定できる．
（注：使用できないものもある）

rotate メソッドの他に，Image オブジェクトの 90 度単位の回転や，上下左右の反転を実行する transpose メソッド
がある．
書き方：

Image オブジェクト.transpose(手法)

引数に指定した手法に従って，Image オブジェクトを回転もしくは反転したオブジェクトを返す．指定できる手法（method）を表 9 に示す．

method1.2.5

表 9: 回転・反転の手法
処理

Image.FLIP LEFT RIGHT

左右反転

Image.FLIP TOP BOTTOM

上下反転

Image.ROTATE 90

反時計回り 90 度回転

Image.ROTATE 180

180 度回転Image.ROTATE 270

時計回り 90 度回転

画像処理

ここでは，Image オブジェクトのピクセル値を処理（画像補正をはじめとする処理）する方法について説明する．

1.2.5.1

色の分解と合成

Image オブジェクトの色成分（バンド）を分解して，別々の Image オブジェクトとして取り出すには split メソッドを使用する．
書き方：

Image オブジェクト.split()

これにより，各色成分に分けられた Image オブジェクトのタプルが返される．例えばモードが ’RGB’ である Image
オブジェクト im があるとき，

23

(r,g,b) = im.split()とすると，r, g, b にそれぞれ赤，緑，青に分解された Image オブジェクトが得られる．これら Image オブジェク
トの画像モードはグレースケールすなわち ’L’ である．

split メソッドとは逆に，グレースケールの Image オブジェクトからカラーの Image オブジェクトを合成するには
merge メソッドを使用する．
書き方：

Image.merge(画像モード, 画像のタプル)

画像モードは表 6 のものを指定する．画像のタプルは画像モードの各色成分（バンド）とするグレースケールの Image
オブジェクトを並べたのもである．
例．グレースケールの Image オブジェクト r, g, b の合成

im2 = Image.merge( ’RGB’, (r,g,b) )これにより，カラーのイメージオブジェクト im2 が得られる．

1.2.5.2

カラー画像からモノクロ画像への変換

Image オブジェクトに対して convert メソッドを使用すると，画像モード（p.21 の表 6）を変換することができる．
これを応用することでカラー画像をグレースケール画像に変換することができる．このことを，以下に例を挙げて示す．
例．カラー画像の読込みと表示>>> from PIL import Image← Pillow ライブラリの読込み

Enter

Enter

>>> im = Image.open(’couple.bmp’)>>> import numpy as np>>> imA = np.asarray(im)Enter←画像ファイルの読込み← NumPy ライブラリの読込み

Enter← Image オブジェクトを NumPy の配列に変換← matplotlib ライブラリの読込み

Enter>>> import matplotlib.pyplot as plt>>> plt.imshow(imA)
Enter←配列に変換した画像を表示<matplotlib.image.AxesImage object at 0x000001F730A04488>>>> plt.show()

Enter←描画の実行

この処理の結果，図 21 のような画像が表示される．

図 21: カラー画像※ NumPy，matplotlib に関しては「3.1 数値計算と可視化のためのライブラリ：NumPy / matplotlib」（p.51〜）で解説する．

次に，この画像を convert メソッドでグレースケールに変換する．

24

例．グレースケール画像への変換（先の例の続き）>>> imGr = im.convert(’L’)>>> imGrA = np.asarray(imGr)

Enter←画像モード ’L’（グレースケール）に変換

Enter← NumPy の配列に変換>>> plt.imshow(imGrA,cmap=plt.cm.gray)Enter←配列に変換した画像を表示<matplotlib.image.AxesImage object at 0x000001F7344F1388>>>> plt.show()

Enter←描画の実行

このように convert メソッドの引数には画像モードを与える．
この処理の結果，図 22 のような画像が表示される．

図 22: グレースケールに変換した画像

1.2.6

描画

Pillow の ImageDraw サブパッケージを使用すると，Image オブジェクトの上に図形や文字を描画することができ
る．描画機能を使用するには次のようにしてパッケージを読み込む．

from PIL import ImageDraw【描画の考え方】

Image オブジェクトに描画するには，対象の Image オブジェクトから取得した Draw オブジェクトに対して各種の描画メソッドを実行する．
例．Image オブジェクト im から Draw オブジェクト drw を取得する

from PIL import ImageDraw
drw = ImageDraw.Draw(im)以後，この drw オブジェクトに対して各種描画メソッドを実行すると im 上に描画される．
【描画処理の例】直線の描画
新規に作成した Image オブジェクトに直線を描画するプログラム pillow01.py を示す．
プログラム：pillow01.py
1
2
3
4
5
6
7
8
9
10
11

# coding : utf -8#モ ジ ュ ー ル の 読 込 みfrom PIL import Image
from PIL import ImageDraw# 白 い Imageオブジェクトの生成
im = Image . new ( ’RGB ’ , (640 ,480) , (255 ,255 ,255) )# Drawオブジェクトの取得
drw = ImageDraw . Draw ( im )# 楕円の描画

25

12
13
14
15
16

drw . ellipse ( [100 ,100 ,539 ,379] , fill =(0 ,0 ,255) )# 直線の描画
drw . line ( [0 ,0 ,639 ,479] , fill =(255 ,0 ,0) , width =32 )im . show ()# ビューワによる表示

解説

7 行目で，白に初期化された Image オブジェクト im を作成し，9 行目で im から Draw オブジェクト drw を取得している．12 行目で drw に対して楕円を，14 行目で直線を描画している．楕円の描画には ellipse メソッド，直線の描画には line メソッドを使用しており，引数に座標リストと，各種のキーワード引数を与えている．キーワード引数の ’ﬁll=’ には色の成分をタプルで与える．また ’width=’ には線の太さをピクセル数で与える．
これにより，im 上に楕円と直線が描かれる．このプログラムを実行すると図 23 のような画像が表示される．

図 23: 実行結果
【描画メソッド】

Pillow で使用できる描画メソッドの一部を紹介（表 10）する．

メソッド

1.2.7

表 10: Draw オブジェクトに対する描画メソッド（一部）働きpoint( 座標リスト, ﬁll=色 )点（複数）を描画する

line( 座標リスト, ﬁll=色, width=太さ )折れ線を描画する

ellipse( 座標リスト, ﬁll=色 )楕円を描画する

arc( 座標リスト, 開始角, 終了角, ﬁll=色 )

円弧を描画する

pieslice( 座標リスト, 開始角, 終了角, ﬁll=色 )パイの形を描画する

rectangle( 座標リスト, ﬁll=色 )長方形を描画する

polygon( 座標リスト, ﬁll=色 )ポリゴン（多角形）を描画する

アニメーション GIF の作成

Image オブジェクトに対する save メソッドに，アニメーション GIF として保存する機能がある．save メソッドの第 1 引数にファイル名を指定する際，拡張子として ‘.gif’ を付けると GIF 形式で保存される．更に save メソッドのキーワード引数としてsave all=True, append images=Image オブジェクトのリスト, duration=フレームの表示時間といったものを指定するとアニメーション GIF として保存される．
例． Image オブジェクト im0, im1, im2, … , imN をアニメーション GIf として保存する手順

imglist = [ im1, im2, … , imN ]← Image オブジェクト群 im1, im2, … , imN のリストを作成

im0.save(’anim.gif’, save all=True, append images=imglist, duration=1000 )←保存

これで，アニメーション GIF が ‘anim.gif’ として保存される．フレームの表示時間にはミリ秒単位の整数値を指定す

26

る．繰り返し表示するアニメーションを作成するには，save メソッドにキーワード引数 loop=True を指定する．

1.2.8

Image オブジェクトから画素の数値配列への変換

NumPy ライブラリ8 を使用すると，Image オブジェクトを構成する画素の配列を数値の配列に変換することができる．これに関しては「3.1.26 画像データの扱い」（p.138）で解説する．

8 「3.1 数値計算と可視化のためのライブラリ：NumPy / matplotlib」（p.51）を参照のこと．

27

2

GUI とマルチメディア

2.1

pygamepygame はウィンドウ上の描画機能や UI デバイス（キーボード，ゲーム用コントロールパッドなど）からの入力をハンドリングする機能，マルチメディア再生の機能を提供するモジュールであり，SDL 9 を用いて構築されたライブラ
リである．pygame はゲームプログラムを構築するために便利な機能を提供するが，ウィンドウ描画と UI デバイスのハンドリングを実現するための高速でコンパクトな汎用ライブラリと見るべきである．本書では pygame の基本的な使用方法について解説する．pygame に関する情報はインターネットサイト https://www.pygame.org/ を参照のこと．

pygame の使用に先立って，次のようにして必要なモジュールを読み込んでおく必要がある．
import pygame
また，pygame 配下の各種モジュールを読み込むことが必要になることがある．
例．終了イベントを意味する定数 QUIT を読み込む

from pygame.locals import QUIT

基礎事項

2.1.1

pygame の機能を使用するには，最初に init 関数を呼び出して初期化処理をする必要がある．
初期化の例．

pygame.init()
2.1.1.1

Surface オブジェクト

pygame では，画像データなどのピットマップを Surface オブジェクトとして扱う．アプリケーションウィンドウ
も Surface オブジェクトとして生成し，その上に図形や文字を描いたり，画像などの Surface オブジェクトを貼り込む
形で描画を実現する．
アプリケーションウィンドウの Surface オブジェクトは次のようにして生成する．
例．

sf = pygame.display.set mode( (400,300) )この例では横 400 ドット，縦 300 ドットのサイズのウィンドウが生成され，Surface オブジェクト sf として扱われる．
この後，この sf 上に描画したい別の Surface オブジェクトを貼り付けたり，各種の描画メソッドで図形や文字を描く．

pygame の座標系は，多くの GUI ライブラリと共通である．すなわち，左上を原点として，横方向を X 軸（右に行くほど座標値は大），縦方向を Y 軸（下に行くほど座標値は大）とする．

2.1.1.2

アプリケーションの実行ループ

pygame を用いたアプリケーションの基本的な動作は，
1)

描画処理
アプリケーションウィンドウの Surface オブジェクトに対する描画処理である．

2)

イベントハンドリング
イベントキュー10 からイベントを取り出し，対応する処理を実行する．

3)

ディスプレイの更新を繰り返すループである．

9 SDL (Simple DirectMedia Layer) はクロスプラットフォームのマルチメディア用 API であり，グラフィックの描画やサウンドの再生などの機能を提供する．SDL は Windows(Microsoft), OSX(Apple), Linux, iOS(Apple), Android(Google) といった OS で利用できる．
10 イベントは短時間に多くのものが発生する．アプリケーションが受け取ったイベントはイベントキューに蓄積される．

28

pygame は SDL を用いて構築されているため，描画とイベント処理の実行速度が大きい．このため，上記ループにおいてアプリケーション実行のタイミングを適切に制御しなければ，システムの CPU タイムの大きな部分を（不必要に）占有することになる．pygame には，アプリケーション実行のタイミングを制御するための Clock クラスが用意されており，このクラスのオブジェクトを用いて，アプリケーションウィンドウのフレームレートを制御して CPU
タイムの不必要な要求を緩和することができる．具体的には次のようにして，フレームレート制御用のオブジェクトを生成する．

fps = pygame.time.Clock()
この例では fps に Clock オブジェクトが得られており，これに対してフレームレートの設定を行う．
サンプルプログラム pygame00.py を示しながら，pygame のアプリケーションの基本的な動作について説明する．
このプログラムは，ボールの画像をウィンドウに表示して，一定のフレームレートでボールを移動するものである．
ボールはウィンドウの端に衝突すると反射（バウンド）する．
（図 24）

ボールがウィンドウ内でバウンドする．

図 24: pygame00.py を実行したところ
プログラム：pygame00.py
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

# coding : utf -8# モジュールの読み込み
import sys
import pygame
from pygame . locals import QUIT
# pygameの初期化
pygame . init ()w = 400; h = 300
sf = pygame . display . set_mode ( (w , h ) )# アプリケーションウィンドウpygame . display . set_caption ( ’ Application : pygame00 . py ’)
fps = pygame . time . Clock ()# フ レ ー ム レ ー ト 制 御 の た め の Clock オ ブ ジ ェ ク ト# 画像の読み込み
im1 = pygame . image . load ( ’ ball01 . jpg ’)
im1_w = im1 . get_width ()# 画像の横幅の取得
im1_h = im1 . get_height ()# 画像の高さの取得# メインループx = 0; y = 0# ボールの位置
dx = 3; dy = 2 # 移 動 量
while True :sf . fill ( (255 ,255 ,255) )# 背景の色sf . blit ( im1 , (x , y ) )# ボールの描画# イベントキューを処理するループ
for ev in pygame . event . get ():if ev . type == QUIT :# 「終了」イベント

29

31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51

pygame . quit ()print ( ’ quitting ... ’)sys . exit ()# ディスプレイの更新
pygame . display . update ()# フレームレートの設定
fps . tick (30)
# 30 F P S に 設 定# ボール移動（位置変更）の処理
x += dx ; y += dy# 移動
if x + im1_w > w :# ボールが右端に衝突した場合の処理
x = w - im1_w - 1
dx *= -1
elif x < 0:
# ボールが左端に衝突した場合の処理
x = 0
dx *= -1
if y + im1_h > h :# ボールが床に衝突した場合の処理
y = h - im1_h - 1
dy *= -1
elif y < 0:
# ボールが天井に衝突した場合の処理
y = 0
dy *= -1

プログラムの 18〜20 行目でボールの画像 ball01.jpg を load メソッドで読み込んで，その幅と高さを取得（get width
メソッド，get height メソッド）している．

26〜27 行目でボールの画像をアプリケーションウィンドウに表示し，29〜33 行目でイベントハンドリングを行っている．ここでは QUIT イベント（アプリケーションウィンドウの閉じるボタンをクリックしたときに発生）を検出してアプリケーションの終了処理をハンドリングするのみとしている．アプリケーションには短時間に複数のイベントが発生し，それらはイベントキューと呼ばれる待ち行列に蓄積される．29 行目の for 文は，イベントキューからイベントを 1 つずつ取り出し，それを順番にハンドリングするループとなっている．イベントキューのイベント列を取り出すには pygame.event.get() を実行する．イベントキューから取り出された個々のイベントはイベント種別をはじめとする各種のプロパティが保持されている．イベント種別は pygame.locals の中に定数として定義されており，プログ
ラムの 6 行目にあるような形で読み込んで使用するのが一般的である．

35 行目では update メソッドを用いてウィンドウの更新を行い，37 行目では tick メソッドを用いてアプリケーショ
ンウィンドウのフレームレートを設定している．
（引数にフレームレートを与える）
画像の描画は 27 行目にあるように blit メソッドを用いる．
（詳しくは後述）

13 行目の set caption メソッドはウィンドウのタイトルを設定する．
30 行目にあるように，QUIT イベントを受けてこのアプリケーションは終了する．このイベントはアプリケーショ
ンウィンドウの閉じるボタンをクリックしたときに発生する．この際の pygame の終了処理として quit メソッドを実行する．この後，sys.exit() を呼び出してアプリケーションを終了させている．

2.1.2

描画機能

Surface オブジェクトに各種の図形や文字などを表示する方法を説明する．
■ 四角形
塗り潰し：

pygame.draw.rect( Sf, Color, Rect )外周pygame.draw.rect( Sf, Color, Rect, Width )：Surface オブジェクト Sf に対して四角形を描画する．引数に与えるものは次の通り．
Color
Rect
Width

-

(R,G,B) のタプル．値の範囲は 0〜255 の整数値
描画位置 (X,Y) とサイズ W × H の値から成るタプル (X,Y,W,H)
外周を描く場合の線の太さ

■ 楕円
塗り潰し：

pygame.draw.ellipse( Sf, Color, Rect )外周pygame.draw.ellipse( Sf, Color, Rect, Width )：30

Surface オブジェクト Sf に対して楕円を描画する．楕円の位置とサイズは，その楕円に外接する四角形を元に考える．引数に与えるものは次の通り．

Color
Rect
Width

(R,G,B) のタプル．値の範囲は 0〜255 の整数値
描画位置 (X,Y) とサイズ W × H の値から成るタプル (X,Y,W,H)
外周を描く場合の線の太さ

-

■円
塗り潰し：

pygame.draw.circle( Sf, Color, (X,Y), R )外周

pygame.draw.circle( Sf, Color, (X,Y), R, Width )：Surface オブジェクト Sf に対して円を描画する．引数に与えるものは次の通り．
Color
(X,Y)
R
Width

(R,G,B) のタプル．値の範囲は 0〜255 の整数値
円の中心の座標
円の半径外周を描く場合の線の太さ

-

■ 線分
書き方：

pygame.draw.line( Sf, Color, (X1,Y1),(X2,Y2), Width )Surface オブジェクト Sf に対して線分を描画する．引数に与えるものは次の通り．
Color(X1,Y1),(X2.Y2)
Width

-

(R,G,B) のタプル．値の範囲は 0〜255 の整数値
始点と終点の座標
線の太さ

■ 折れ線
書き方：

pygame.draw.lines( Sf, Color, Closing, Plist, Width )Surface オブジェクト Sf に対して折れ線を描画する．引数に与えるものは次の通り．
Color
Closing
Plist
Width

(R,G,B) のタプル．値の範囲は 0〜255 の整数値
始点と終点を結ぶか（True）否か（False）
始点から終点までの座標のリスト．要素は各座標のタプル
線の太さ

-

■ 多角形
塗り潰し：

pygame.draw.polygon( Sf, Color, Plist )外周pygame.draw.polygon( Sf, Color, Plist, Width )：Surface オブジェクト Sf に対して多角形を描画する．引数に与えるものは次の通り．
Color
Plist
Width

-

(R,G,B) のタプル．値の範囲は 0〜255 の整数値
頂点の座標のリスト．要素は各座標のタプル
外周を描く場合の線の太さ■ 画像
ファイルから読込み：

pygame.image.load( Fname )画像ファイルをパス Fname から読み込んで Surface オブジェクトとして返す．
ファイルに保存：pygame.image.save( S, Fname )Surface オブジェクト S を画像ファイル Fname（パス名）に保存する．
Surface オブジェクトを別の Surface オブジェクトに貼り付けるには blit メソッドを使用する．
例．Surface オブジェクト s1 を別の Surface オブジェクト s2 に貼り付ける

s2.blit(s1,(20,10))
この例では，Surface オブジェクト s1 を，s2 上の (20,10) の位置に貼り付けている．
アプリケーションウィンドウも Surface オブジェクトであり，画像を表示するには同様の方法を用いる．

31

■ 文字列pygame では文字列は Surface オブジェクトとして表示する．この際，フォントとサイズ，スタイルなどの情報を保持する Font オブジェクトを生成し，これを用いて文字列データを Surface オブジェクトに変換する．Font オブジェ
クトを生成するには SysFont メソッドを使用する．

Font オブジェクトの生成：

pygame.font.SysFont(フォント名, サイズ)

注）フォント名に None を指定すると自動的にデフォルトのフォントが採用されるが，その場合は日本語が使用できないことが多い．

Font オブジェクトを用いて文字列を Surface オブジェクトに変換するには render メソッドを用いる．
文字列から Surface を生成：

Font オブジェクト.render(文字列, アンチエイリアス指定, 色)「アンチエイリアス指定」は True か False で，「色」は RGB 値のタプルで与える．
例．文字列から Surface オブジェクトを生成

fnt = pygame.font.SysFont(’ipa ゴシック’,32)
txt = fnt.render(’ 日本語のメッセージ’, True, (255,255,255) )この結果，文字列をビットマップとして保持する Surface オブジェクト txt が生成される．
フォント名の取得：

pygame で利用できるフォント名は get fonts メソッドを使用することで調べることができる．このメソッドを実行すると利用可能なフォント名のリストが返される．次に示すプログラム pygame03.py を実行すると，利用可能なフォント名の一覧が表示される．
プログラム：pygame03.py
1
2
3
4
5
6
7
8
9
10
11
12

# coding : utf -8# モジュールの読み込み
import pygame# pygameの初期化
pygame . init ()# フォントリストの取得と表示
fl = pygame . font . get_fonts ()for m in fl :print ( m )このプログラムを実行すると，次の例のようにフォント名が表示される．
arial
arialblack
calibri：（途中省略）：
ipap 明朝
ipaex ゴシック
ipaex 明朝

2.1.2.1

描画のサンプルプログラム

先に解説した描画機能を使用したサンプルプログラム pygame01.py を示す．
プログラム：pygame01.py
1
2
3
4
5
6
7

# coding : utf -8# モジュールの読み込み
import sys
import pygame
from pygame . locals import QUIT

32

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

# pygameの初期化
pygame . init ()sf = pygame . display . set_mode ( (640 ,480) )# アプリケーションウィンドウpygame . display . set_caption ( ’ Application : pygame01 . py ’)
fps = pygame . time . Clock ()# フ レ ー ム レ ー ト 制 御 の た め の Clock オ ブ ジ ェ ク ト# メインループ
while True :# 四角形（塗りつぶし）の描画
pygame . draw . rect ( sf , (255 ,0 ,0) , (20 ,20 ,100 ,50))# 四角形（枠）の描画
pygame . draw . rect ( sf , (0 ,255 ,0) , (140 ,20 ,100 ,50) , 20 )# 円（塗りつぶし）の描画
pygame . draw . circle ( sf , (0 ,0 ,255) , (70 ,140) , 50 )# 円（線による円周）の描画
pygame . draw . circle ( sf , (255 ,255 ,0) , (190 ,140) , 50 , 20 )# 楕円（塗りつぶし）の描画
pygame . draw . ellipse ( sf , (255 ,0 ,255) , (20 ,200 ,230 ,80) )# 楕円（線による周）の描画
pygame . draw . ellipse ( sf , (0 ,255 ,255) , (20 ,290 ,230 ,80) , 20 )# 線分の描画
pygame . draw . line ( sf , (255 ,255 ,255) , (20 ,390) ,(250 ,390) , 20 )# 折れ線の描画（開放端）
plst = [(20 ,460) , (125 ,415) , (125 ,460) , (250 ,415)]
pygame . draw . lines ( sf , (127 ,127 ,127) , False , plst , 20 )# 折れ線の描画（始点と終点を結ぶ）
plst = [(270 ,240) , (300 ,20) , (620 ,20) , (620 ,120) , (330 ,120)]
pygame . draw . lines ( sf , (255 ,255 ,255) , True , plst , 15 )# 文字の描画（システムフォント）
fnt = pygame . font . SysFont ( ’ i p a ゴ シ ッ ク ’ ,32)
# システムフォント
txt = fnt . render ( ’ 日 本 語 の メ ッ セ ー ジ ’ , True , (255 ,255 ,255) )txt_rct = txt . get_rect ()# テキストオブジェクトの領域サイズ
sf . blit ( txt ,(320 ,50))# ポリゴンの描画（塗りつぶし）plst = [(310 ,280) , (380 ,150) , (550 ,150) , (620 ,280)]
pygame . draw . polygon ( sf , (255 ,0 ,255) , plst )# ポリゴンの描画（線による周）
buf = pygame . Surface ( (330 ,160) )# バッファ
plst = [(10 ,10) , (80 ,150) , (250 ,150) , (320 ,10)] # バ ッ フ ァ 上 の 座 標
pygame . draw . polygon ( buf , (255 ,255 ,0) , plst , 20 )# バッファに描画
sf . blit ( buf , (300 ,300) )# バッファをウィンドウへ# イベントキューを処理するループ
for ev in pygame . event . get ():if ev . type == QUIT :# 「終了」イベント
pygame . quit ()print ( ’ quitting ... ’)sys . exit ()# ディスプレイの更新
pygame . display . update ()# フレームレートの設定
fps . tick (4) # 4 F P S に 設 定

このプログラムを実行すると図 25 のようなウィンドウが表示される．
■ 回転，拡縮など画像に対して回転，拡大，縮小をするには，元の画像（Surface オブジェクト）に対してそれらの処理を施したものを生成して，それを別の Surface オブジェクトに貼り付けるという手順を踏む．

33

各種の描画機能を実行したサンプル

図 25: pygame01.py を実行したところ
回転，拡縮のためのメソッド
回転：

pygame.transform.rotate(Sur,Angle)

サイズ変更：

pygame.transform.scale(Sur,NewSize)

これらメソッドは Surface オブジェクト Sur を回転，拡縮し，その結果として得られる Surface オブジェクトを返す．
元の Sur は変更されない．回転処理において Angle には回転角を反時計回りで指定する．単位は 360 進法の「度」である．サイズ変更において，NewSize には幅と高さのタプル (W,H) で与える．要素は整数で与えること．

2.1.2.2

回転，拡縮のサンプルプログラム

画像の回転，拡縮を応用したアニメーションを表示するサンプルプログラムを示す．図 26 に示す画像を回転するア
ニメーションを表示するプログラムを pygame02.py に，拡縮するアニメーションを表示するプログラムを pygame04.pyに示す．

pygame logo.png

図 26: この画像を回転，拡縮するプログラム：pygame02.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18

# coding : utf -8# モジュールの読み込み
import sys
import pygame
from pygame . locals import QUIT
# pygameの初期化
pygame . init ()sf = pygame . display . set_mode ( (320 ,240) )# アプリケーションウィンドウpygame . display . set_caption ( ’ Application : pygame02 . py ’)
fps = pygame . time . Clock ()# フ レ ー ム レ ー ト 制 御 の た め の Clock オ ブ ジ ェ ク ト# 画像の読込み
im1 = pygame . image . load ( ’ pygame_logo . png ’)
agl = 0.0
# 初期角度

34

19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38

# メインループ
while True :sf . fill ( (0 ,0 ,0) ) # 毎 フ レ ー ム ク リ ア す る# 画像の回転と表示
im2 = pygame . transform . rotate ( im1 , agl %360)
sf . blit ( im2 , (50 ,10) ) # ウ ィ ン ド ウ に 転 送
agl += 2.4 # 次 回 の 角 度# 回転処理# イベントキューを処理するループ
for ev in pygame . event . get ():if ev . type == QUIT :# 「終了」イベント
pygame . quit ()print ( ’ quitting ... ’)sys . exit ()# ディスプレイの更新
pygame . display . update ()# フレームレートの設定
fps . tick (30)
# 30 F P S に 設 定

プログラム：pygame04.py
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

# coding : utf -8# モジュールの読み込み
import sys
import pygame
from pygame . locals import QUIT
# pygameの初期化
pygame . init ()sf = pygame . display . set_mode ( (320 ,120) )# アプリケーションウィンドウpygame . display . set_caption ( ’ Application : pygame04 . py ’)
fps = pygame . time . Clock ()# フ レ ー ム レ ー ト 制 御 の た め の Clock オ ブ ジ ェ ク ト# 画像の読込み
im1 = pygame . image . load ( ’ pygame_logo . png ’)
im1_w = im1 . get_width ()im1_h = im1 . get_height ()rat = 0.0
# 初期比率dr = 0.02# メインループ
while True :sf . fill ( (0 ,0 ,0) ) # 毎 フ レ ー ム ク リ ア す る# 画像の回転と表示
im2 = pygame . transform . scale ( im1 ,( int ( rat * im1_w ) , int ( rat * im1_h )) )sf . blit ( im2 , (10 ,10) ) # ウ ィ ン ド ウ に 転 送
rat += dr# 次回の比率if rat > 1.5:
rat = 1.5
dr *= -1
elif rat < 0.0:
rat = 0.0
dr *= -1
# イベントキューを処理するループ
for ev in pygame . event . get ():if ev . type == QUIT :# 「終了」イベント
pygame . quit ()print ( ’ quitting ... ’)sys . exit ()# ディスプレイの更新
pygame . display . update ()# フレームレートの設定
fps . tick (30)
# 30 F P S に 設 定

35# 拡縮処理■ Surface オブジェクトのサイズ

Surface オブジェクトに対して get width，get height メソッドを引数なしで使用することで幅と高さが得られる．
2.1.3

キーボードとマウスのハンドリング

キーボードやマウスのイベントとして代表的なもの（イベント種別）を表 11 に挙げる．これらイベントは pygame.localsの中に定数として定義されており，それらを読み込んで使用することができる．

表 11: マウスとキーボードの代表的なイベント
イベント定数

イベントの種類

利用できるイベント属性（プロパティ）の一部

MOUSEBUTTONDOWN
MOUSEBUTTONUP
MOUSEMOTIONKEYDOWN

マウスのボタンが押された
マウスのボタンが放された
マウスが動いたキーボードが押された

KEYUP

キーボードが放された

pos,button：位置とボタン
pos,button：位置とボタン
pos,buttons：位置とボタンタプル
key,mod,unicode：キー番号とモディファイア，
文字コード体系（エンコーディング）
key,mod：キー番号とモディファイア

キーボードとマウスのイベントをハンドリングするサンプルプログラム pygame05.py を示す．
プログラム：pygame05.py
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

# coding : utf -8# モジュールの読み込み
import sys
import pygame
from pygame . locals import QUIT , MOUSEBUTTONDOWN , MOUSEBUTTONUP , \MOUSEMOTION , KEYDOWN , KEYUP# pygameの初期化
pygame . init ()sf = pygame . display . set_mode ( (320 ,240) )# アプリケーションウィンドウpygame . display . set_caption ( ’ Application : pygame05 . py ’)
fps = pygame . time . Clock ()# フ レ ー ム レ ー ト 制 御 の た め の Clock オ ブ ジ ェ ク ト# メインループ
while True :# イベントキューを処理するループ
for ev in pygame . event . get ():if ev . type == QUIT :# 「終了」イベント
pygame . quit ()print ( ’ quitting ... ’)sys . exit ()elif ev . type == MOUSEBUTTONDOWN :print ( ’ Mouse button was pressed :\ t ’ , ev . pos , ev . button )elif ev . type == MOUSEBUTTONUP :print ( ’ Mouse button was released :\ t ’ , ev . pos , ev . button )elif ev . type == MOUSEMOTION :print ( ’ Mouse is moving :\ t \t ’ , ev . pos , ev . buttons )elif ev . type == KEYDOWN :print ( ’ A key was pressed :\ t \t ’ , ev . key , ev . mod , ev . unicode )elif ev . type == KEYUP :print ( ’ The key was released :\ t \t ’ , ev . key , ev . mod )# ディスプレイの更新
pygame . display . update ()# フレームレートの設定
fps . tick (12)# 12 F P S に 設 定

このプログラムを実行すると小さなウィンドウが表示され，キーボード，マウスからのイベントを受けて，それらイベントの各種プロパティの値が表示されることが確認できる．

36

2.1.4

音声の再生

pygame は WAV 形式音声データに加えて，MP3 11 や Ogg Vorbis 12 といったフォーマットの音声データを再生することができる．pygame の音声再生機能は pygame.mixer.music パッケージにあり，例えば音声データ ’dat1.mp3’ を読込んで再生するには次のように記述する．

pygame.mixer.music.load(’dat1.mp3’)
pygame.mixer.music.play()
pygame.mixer.music パッケージの主要な機能を表 12 に挙げる．
表 12: サウンド再生のための主な機能
機能（関数）

説明load(Fname)play( )stop( )
pause( )unpause( )rewind( )fadeout( t )Fname のパスから音声データを読み込む
読み込まれた音声データを再生する
再生中の音声を停止する
再生中の音声を一時停止する
一時停止した音声の再生を再開する
再生中の音声を巻き戻す．
（先頭に戻す）再生中の音声をフェードアウトして停止する
フェードアウトタイムは t で指定する．
（単位：ミリ秒）
再生中の位置（時刻）を返す．
（単位：ミリ秒）
再生中の位置（時刻）t を指定する．
（単位：ミリ秒）
音量の設定値（0〜1.0）を取得する
音量を設定（0.0 ≤ v ≤ 1.0）する
音声が再生中であれば True を，そうでなければ False を返す

get pos( )set pos( t )get volume( )set volume( v )get busy( )注）再生位置の制御に関しては，扱う音声フォーマットによって扱いが異なる．

音声データを再生するプログラムの例 pygame06.py をに示す．
プログラム：pygame06.py
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

# coding : utf -8# モジュールの読み込み
import sys
import pygame
from pygame . locals import QUIT
# pygameの初期化
pygame . init ()sf = pygame . display . set_mode ( (320 ,240) )# アプリケーションウィンドウpygame . display . set_caption ( ’ Application : pygame06 . py ’)
fps = pygame . time . Clock ()# フ レ ー ム レ ー ト 制 御 の た め の Clock オ ブ ジ ェ ク ト# サウンドデータの読込みと再生
pygame . mixer . music . load ( ’ sound02 . ogg ’)pygame . mixer . music . play ()# メインループ
while True :# イベントキューを処理するループ
for ev in pygame . event . get ():if ev . type == QUIT :# 「終了」イベント
pygame . quit ()print ( ’ quitting ... ’)sys . exit ()# 再生が終了したときの処理

11 MP3（MPEG-1 Audio Layer-3）：最も広く普及している音声圧縮フォーマットである．厳密には，特許に関連する事情のため，

完全に自由に使える技術ではない．したがって，商用の利用には注意が必要である．
12 Ogg Vorbis：Vorbis コーデックで圧縮伸張し，Ogg コンテナにサウンドを格納する音声フォーマットである．オープンソース

であり自由に利用できる．他の圧縮フォーマットと比べても音質は劣らない．

37

30
31
32
33
34
35
36
37
38
39
40
41
42

if pygame . mixer . music . get_busy ():passelse :
print ( ’ music has finished . ’)pygame . quit ()sys . exit ()print ( ’ Playing : ’ , pygame . mixer . music . get_pos () , ’ msec ’ )# ディスプレイの更新
pygame . display . update ()# フレームレートの設定
fps . tick (2) # 2 F P S に 設 定

このプログラムを実行すると，小さなウィンドウを表示した後，音声ファイル’sound02.ogg’ を読み込んで再生を開始する．再生中は再生の経過時間が標準出力にミリ秒単位で表示される．

2.1.4.1

Sound オブジェクトを用いる方法

Sound オブジェクトを用いても音声の再生ができる．
Sound オブジェクトの生成：

pygame.mixer.Sound(’ 音声ファイルのパス’)

この処理の結果として Sound オブジェクトが得られ，表 13 のようなメソッドが使用できる．
表 13: Sound オブジェクトに対する主なメソッド
メソッド
解説
メソッド
解説

play()

再生開始

stop()

再生終了

get volume()

音量の取得

set volume()

音量の設定

get length()

再生時間の取得

Sound オブジェクトを用いて先に示したサンプルプログラム pygame06.py と同等の機能を実現するプログラム
pygame07.py を示す．
プログラム：pygame07.py
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

# coding : utf -8# モジュールの読み込み
import sys
import pygame
from pygame . locals import QUIT
# pygameの初期化
pygame . init ()sf = pygame . display . set_mode ( (320 ,240) )# アプリケーションウィンドウpygame . display . set_caption ( ’ Application : pygame07 . py ’)
fps = pygame . time . Clock ()# フ レ ー ム レ ー ト 制 御 の た め の Clock オ ブ ジ ェ ク ト# サウンドデータの読込みと再生
snd = pygame . mixer . Sound ( ’ sound02 . ogg ’)print ( ’ 長 さ : ’ , snd . get_length ())
print ( ’ 音 量 : ’ , snd . get_volume ())
snd . play ()# メインループ
while True :# イベントキューを処理するループ
for ev in pygame . event . get ():if ev . type == QUIT :# 「終了」イベント
pygame . quit ()print ( ’ quitting ... ’)sys . exit ()38

# 再生が終了したときの処理
if pygame . mixer . get_busy ():passelse :
print ( ’ music has finished . ’)pygame . quit ()sys . exit ()

31
32
33
34
35
36
37
38
39
40
41
42

# ディスプレイの更新
pygame . display . update ()# フレームレートの設定
fps . tick (2) # 2 F P S に 設 定

このプログラムの 32 行目にあるように，Sound オブジェクトの再生においては，その終了を pygame.mixer.get busy()で検出する．

2.1.4.2

Sound オブジェクトから NumPy の配列への変換

音声データを NumPy ライブラリを用いて解析するには，Sound オブジェクトが持つ音声のデータ列を NumPy 13の配列データに変換する必要がある．

NumPy 配列への変換：

pygame.sndarray.array( Sound オブジェクト )この処理によって Sound オブジェクトの音声データ列が NumPy の配列として得られる．
ファイルから読み込んだ音声データを NumPy の配列にして，波形グラフを表示するプログラム pygame08.py を示
す．
プログラム：pygame08.py
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

# coding : utf -8# モジュールの読み込み
import pygame
import numpy as np
import matplotlib . pyplot as plt# pygameの初期化
pygame . mixer . pre_init ( frequency =44100 , size = -16 , channels =2 , buffer =4096)
pygame . init ()# サウンドデータの読込み
snd = pygame . mixer . Sound ( ’ aaa . wav ’)print ( ’ 長 さ : ’ , snd . get_length ())
print ( ’ 音 量 : ’ , snd . get_volume ())# NumPy配列への変換
ar = pygame . sndarray . array ( snd )print ( ’ 配 列 の 形 状 : ’ , ar . shape )print ( ’ 配 列 の 型 : ’ , ar . dtype )# 左右の分離arL = ar [: ,0]arR = ar [: ,1]# 左チャンネル# 右チャンネル# プロット( fig , ax ) = plt . subplots ( 2 , 1 , figsize =(8 ,4) )plt . subplots_adjust ( hspace =0.5)
ax [0]. plot ( arL )ax [0]. set_title ( ’ Left ’)ax [1]. plot ( arR )ax [1]. set_title ( ’ Right ’)plt . show ()このプログラムの 9 行目で pygame で再生する音声に関する設定が pygame.mixer.pre init によって行われる．これはpygame.init() に先立って実行する．pygame.mixer.pre init のキーワード引数は次のようなものである．
13 「3.1 数値計算と可視化のためのライブラリ：NumPy / matplotlib」（p.51）で解説する．

39

frequency=サンプリング周波数

サンプリング周波数を設定する（単位：Hz）

size=量子化ビット数

量子化ビット数（ビット長）を設定する．
負の値を与えると，符号付き整数の形でサンプリングが行われる．

channels=チャンネル数

ステレオの場合は 2 を，モノラルの場合は 1 を設定する．

buﬀer=バッファサイズ

通常は 4096 を設定しておく．

このプログラムを実行するとターミナルウィンドウに次のように表示される．
pygame 1.9.6
Hello from the pygame community.
長さ: 0.401995450258255
音量: 1.0
配列の形状: (17728, 2)配列の型: int16

https://www.pygame.org/contribute.html

同時に図 27 のような波形がプロットされる．

図 27: pygame08.py の実行で表示される波形のグラフ

2.1.5

スプライトの利用先に挙げたプログラム pygame00.py では，1 つのボールがウィンドウ内で移動する様子を示した．プログラムの基本的な流れとしては概ね，

1. ウィンドウ内の消去
2. ゲームフィールド 1 場面の状態（画像の位置など）の生成
3. ゲームフィールド 1 場面の表示とウィンドウの更新というものであり，これらを全て「メインループ」内で記述している．
実際のゲームでは，ゲームフィールド内で複数のキャラクタ（画像部品など）がそれぞれ独自の動きをすることが多く，全ての画像部品の動きを表現するための変数などを個別に用意して，メインループ内で全ての変数の変化を記述するのは非常に煩雑な作業となる．
ここで紹介するスプライトを使用すると，ゲームフィールド内にある画像部品を別々のオブジェクトとして管理で
き，ゲーム開発が大幅に簡素化できる．具体的には，ゲームフィールドに登場するそれぞれのキャラクタを個別のオブジェクト（Sprite クラス）として生成して扱い，個々のキャラクタの動きを，そのオブジェクトに対するメソッドとして実装するというスタイルを取る．
【Sprite クラス】

Sprite クラスは，ゲームキャラクタの画像を image 属性として，その位置とサイズを rect 属性として保持する．
ゲームキャラクタはゲーム展開の個々のフレームで位置を始めとする状態を更新することで動きを実現する．Sprite オ

40

ブジェクトの状態を変化させる（更新する）ためのメソッドとして update，それを Surface に描画するためのメソッドとして draw があり，Sprite クラスの拡張クラスの定義でそれらをオーバーライドして，各種スプライトに独自の動きを実現する．Sprite クラスは pygame.sprite.Sprite としてアクセスできる．
■ サンプルプログラム 1
次に示すサンプルプログラム pygame sprt1.py は，先に挙げたプログラム pygame00.py と類似の動作（ボールがバウンドするアニメーション）をするものである．これに沿ってスプライトの最も基本的な取り扱いについて説明する．
プログラム：pygame sprt1.py
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

# coding : utf -8# モジュールの読込み
import sys
import pygame
from pygame . locals import QUIT
from pygame . locals import Rect
pygame . init ()# 終了イベント# 矩形クラス# pygameの初期化###################################################### スプライト用クラスの定義## pygame . sprite . Sprite を 継 承 し て 拡 張 す る## 基本プロパティ：
#
#
image
スプライト用画像##
rect
スプライトの位置とサイズ（矩形）##vx , vy 移動時の差分（移動量）######################################################
class MySprite ( pygame . sprite . Sprite ):def __init__ ( self , imgFname ,x ,y , vx , vy ):pygame . sprite . Sprite . __init__ ( self )self . image = pygame . image . load ( imgFname ). convert_alpha ()width = self . image . get_width ()height = self . image . get_height ()self . rect = Rect (x ,y , width , height )self . vx = vx
self . vy = vy
def update ( self ):global w , h# ウィンドウサイズ（大域変数）
if self . rect . left < 0:self . vx = - self . vx
self . rect . left = 0
if self . rect . right > w :self . vx = - self . vx
self . rect . right = w
if self . rect . top < 0:self . vy = - self . vy
self . rect . top = 0
if self . rect . bottom > h :self . vy = - self . vy
self . rect . bottom = hself . rect . move_ip ( self . vx , self . vy )def draw ( self , screen ):screen . blit ( self . image , self . rect )###################################################### ゲームフィールドの準備######################################################
w = 400;
h = 300# ウィンドウサイズ# ウ ィ ン ド ウ （ Surface）の生成
sf = pygame . display . set_mode ( (w , h ) )pygame . display . set_caption ( ’ Sprite Test (1) ’)# Clockオブジェクトの生成（フレームレート制御関連）
fps = pygame . time . Clock ()###################################################### スプライトの生成######################################################

41

60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80

spr1 = MySprite ( ’ ball . png ’ , 0 ,0 , 5 ,3 )###################################################### メインループ######################################################
while True :# フレームレート設定（毎回）
fps . tick (30)
# ウィンドウ消去（毎回）
sf . fill ( (0 ,0 ,0) )# 毎回，真っ暗にする# スプライト描画
spr1 . update ()# スプライトの状態の更新
spr1 . draw ( sf )# スプライトの表示# イベント検出部
for ev in pygame . event . get ():if ev . type == QUIT :# 終了処理pygame . quit ()print ( ’ 終 了 し ま す ． ’ )sys . exit ()# ウィンドウの更新
pygame . display . update ()このプログラムでは，Sprite クラスの拡張クラスとして MySprite クラスを定義して，このクラスのインスタンスとしてゲームキャラクタを取り扱う．MySprite クラスはゲームキャラクタ用の画像（image 属性）と，その位置とサイズの情報（rect 属性）を保持するだけでなく，フレーム更新時の位置の変化量も vx, vy プロパティとして保持するように実装されている．MySprite クラスのインスタンスを生成する際，コンストラクタの引数に，画像のファイル名，それに初期の位置と変化量を与える．
メインループ内では，ウィンドウの消去とスプライトの状態の更新，表示を繰り返し行なっている．ボールの絵として表示されるスプライト spr1 は，フレームの更新の度に，・ 移動量プロパティ vx, vy に基づく位置の変更
・ ウィンドウの端に衝突したかどうかの判定と，それに基づく移動方向の変更
を update メソッドで行っている．実際の表示は draw メソッドで行っている．

rect プロパティは配下に top, bottom, left, right プロパティを持っており，それぞれ上下左右の座標値に対応している．これらプロパティの値を参照して，ウィンドウの端に衝突したことを判定している．
このプログラムを実行した様子を図 28 に示す．

図 28: 1 個のボールがバウンドするアニメーション■ サンプルプログラム 2
複数のスプライトを保持する Group クラスを使用すると，複数のゲームキャラクタを同時に扱うことが容易になる．

Group クラスは pygame.sprite.Group としてアクセスできる．
先のプログラム pygame sprt1.py を変更して，複数のスプライトを同時に扱う形にしたプログラム pygame sprt2.pyを次に示す．
プログラム：pygame sprt2.py
1
2# coding : utf -8# モジュールの読込み

42

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

import sys
import pygame
from pygame . locals import QUIT
from pygame . locals import Rect
pygame . init ()# 終了イベント# 矩形クラス# pygameの初期化###################################################### スプライト用クラスの定義## pygame . sprite . Sprite を 継 承 し て 拡 張 す る## 基本プロパティ：
#
#
image
スプライト用画像##
rect
スプライトの位置とサイズ（矩形）##vx , vy 移動時の差分（移動量）######################################################
class MySprite ( pygame . sprite . Sprite ):def __init__ ( self , imgFname ,x ,y , vx , vy ):pygame . sprite . Sprite . __init__ ( self )self . image = pygame . image . load ( imgFname ). convert_alpha ()width = self . image . get_width ()height = self . image . get_height ()self . rect = Rect (x ,y , width , height )self . vx = vx
self . vy = vy
def update ( self ):global w , h# ウィンドウサイズ（大域変数）
if self . rect . left < 0:self . vx = - self . vx
self . rect . left = 0
if self . rect . right > w :self . vx = - self . vx
self . rect . right = w
if self . rect . top < 0:self . vy = - self . vy
self . rect . top = 0
if self . rect . bottom > h :self . vy = - self . vy
self . rect . bottom = hself . rect . move_ip ( self . vx , self . vy )def draw ( self , screen ):screen . blit ( self . image , self . rect )###################################################### ゲームフィールドの準備######################################################
w = 400;
h = 300# ウィンドウサイズ# ウ ィ ン ド ウ （ Surface）の生成
sf = pygame . display . set_mode ( (w , h ) )pygame . display . set_caption ( ’ Sprite Test (2) ’)# Clockオブジェクトの生成（フレームレート制御関連）
fps = pygame . time . Clock ()###################################################### スプライトの生成######################################################
sg = pygame . sprite . Group ()# スプライトグループの生成
for i in range (5):spr = MySprite ( ’ ball . png ’ , i *80 , i *60 , 5 ,3 )sg . add ( spr )###################################################### メインループ######################################################
while True :# フレームレート設定（毎回）
fps . tick (30)
# ウィンドウ消去（毎回）
sf . fill ( (0 ,0 ,0) )# 毎回，真っ暗にする# スプライト描画
sg . update ()

43

75
76
77
78
79
80
81
82
83

sg . draw ( sf )# イベント検出部
for ev in pygame . event . get ():if ev . type == QUIT :# 終了処理pygame . quit ()print ( ’ 終 了 し ま す ． ’ )sys . exit ()# ウィンドウの更新
pygame . display . update ()このプログラムの前半部は pygame sprt1.py と同じであるが，複数のスプライトをまとめる Group である sg を生成し，そこに 5 個の同じスプライトを初期位置を変えて登録するものである．メインループ内でも，スプライトグルー
プである sg に対して update し，draw している．
このプログラムを実行した様子を図 29 に示す．

図 29: 5 個のボールがバウンドするアニメーション

44

2.2

Eel

Eel は HTML5 の枠組みで Python アプリケーションの GUI を実現するためのモジュールである．HTML5 でユー
ザインターフェースを構築するための基盤として Google Chrome ブラウザを使用する．このため，Google Chome
ブラウザから Python で記述した関数を呼び出す形のアプリケーション構築となる．また Google Chrome ブラウザの全機能が利用できるため，HTML5 による表現力の高いインターフェースが構築できるだけでなく，JavaScript とPython の両方の機能を組み合わせた形でアプリケーション全体を作り上げることができる．
本書では Eel に関する基本的な事柄について解説する．Eel に関する詳しい情報はインターネットサイト

https://pypi.org/project/Eel/で公開されているのでそちらを参照のこと．

2.2.1

基礎事項

Eel を用いたアプリケーションは
1) Python で記述したスクリプト
2) GUI 構築用の HTML5 コンテンツから成る．更に 2) は HTML，JavaScript，CSS を記述したファイル群から成る．
次に，文字を表示するだけの簡単なサンプルプログラム（図 30）の実装を示す．

図 30: 最も簡単な Eel アプリケーション
このアプリケーションは Python で記述したプログラム本体 test01.py と，HTML で記述した UI コンテンツ ui01.htmlの 2 つから成る．
（下記参照）
プログラム：test01.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16

# coding : utf -8# モジュールの読込み
import eel# Chrome起動オプション
op = {’ mode ’: ’ chrome - app ’ ,# 独自アプリケーションの形式#’ mode ’: ’ chrome ’ ,# Chromeブラウザの形式’ chromeFlags ’:[ ’ - - window - size =550 ,250 ’] # G o o g l e C h r o m e 起 動 オ プ シ ョ ン}# UI初期化
eel . init ( ’. ’)# ChromeでUIを起動
eel . start ( ’ ui01 . html ’ , options = op )UI 用 HTML ファイル：ui01.html
1
2
3< html >< head >

45

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

< meta charset = ’ utf -8 ’ >< title > test01 </ title ><! - - ス タ イ ル 設 定 -->< style type =" text / CSS " >p {margin : 0 pt ;font - size : 24 pt ;color : #666666;
line - height : 1.5 em ;}</ style ><! - - E e l 用 に 下 記 1 行 が 必 要 -->< script type =" text / javascript " src ="/ eel . js " > </ script ></ head ><! - - U I 本 体 -->< body ><p > E e l を 使 う と ， </ p ><p > Google C h r o m e ブ ラ ウ ザ で </ p ><p > G U I を 構 築 す る こ と が で き ま す ． </ p ></ body ></ html >各種ファイル群の名前は任意に決めて良いが，構築するアプリケーション毎に 1 のフォルダにまとめるべきである．

test01.py の冒頭ではimport eel
として Eel モジュールを読み込んでいる．また，GUI となる HTML コンテンツ内では Eel の機能を使用するために<script type="text/javascript" src="/eel.js"></script>を記述する．
（ui01.html の 17 行目）この記述の中の eel.js という JavaScript のプログラムは Eel の動作によって自動的に与えられる．

Eel による GUI の起動は次の 2 つのステップから成る．
● ステップ１
プログラムの 13 行目にあるように，init メソッドを実行する．この際，引数には，当該アプリケーションを収める
ディレクトリのパスを与える．
● ステップ２
プログラムの 16 行目にあるように，start メソッドを実行する．この際，第 1 引数には，UI となる HTML コンテ
ンツのファイル名を文字列の型で与え，GoogleChrome ブラウザの起動時に与えるオプション列を辞書オブジェクトとしてキーワード引数 ‘option=’ に与える．

2.2.1.1

Chrome の起動モード

先の実行例では，Chrome の起動オプション ’mode’ に ’chrome-app’ を指定しているが，これを ’chrome’ にする（8 行目のコメント）と，GUI のウィンドウが Web ブラウザの形式（図 31）となる．

2.2.2

Python/JavaScript で記述した関数の呼出し

Python スクリプトの中に定義を記述した関数を，Web ブラウザ側から呼び出して実行することができる．そのためには，Python 側の def 文（関数定義）の直前に@eel.exposeというデコレータを記述する必要がある．また，Web ブラウザから使用する Python の関数の定義は，init メソッドの行以降，start メソッドの行までの間に記述すること．

46

図 31: Web ブラウザ形式の UIHTML から Python の関数を呼び出す，あるいは Python 側から HTML 中の JavaScript の関数を呼び出す方法について例を挙げて説明する．HTML で構成した UI への操作（ボタンのクリック）を受けて Python 側の関数を呼び出すプログラムについて考える．
（図 32）→「現在時刻」ボタンをクリックすると時刻が表示される

図 32: HTML から Python の関数を呼出して時刻を表示
これを実装した例を test02.py，ui02.html に示す．
プログラム：test02.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22

# coding : utf -8# モジュールの読込みfrom datetime import datetime
import eel# Chrome起動オプション
op = {’ mode ’: ’ chrome - app ’ ,# 独自アプリケーションの形式’ chromeFlags ’:[ ’ - - window - size =300 ,150 ’] # G o o g l e C h r o m e 起 動 オ プ シ ョ ン}# UI初期化
eel . init ( ’. ’)# UIから呼び出す関数@eel . expose
def pyFun1 ():t = str ( datetime . now ())
eel . jsFun2 ( t )# ChromeでUIを起動
eel . start ( ’ ui02 . html ’ , options = op )UI 用 HTML ファイル：ui02.html
1
2
3
4
5
6
7
8

< html >< head >< meta charset = ’ utf -8 ’ >< title > test02 </ title >< style type =" text / css " ># t1 {

47

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

width : 200 px ;}</ style ><! - - E e l 用 に 下 記 1 行 が 必 要 -->< script type =" text / javascript " src ="/ eel . js " > </ script ><! - - U I 制 御 用 関 数 -->< script type =" text / javascript " >// P y t h o n か ら 呼 び 出 す 関 数
eel . expose ( jsFun2 );function jsFun2 ( v ) {t1 . value = v ;}</ script ></ head ><! - - U I 本 体 -->< body >< input type =" button " value =" 現 在 時 刻 " onClick =" eel . pyFun1 ()" > < br >< input type =" text " value ="" id =" t1 " > < br >< input type =" button " value =" 終 了 " onClick =" window . close ()" ></ body ></ html >test02.py の 17〜19 行目に定義されている関数 pyFun1 は現在時刻を求めて，UI 側のテキストフィールドにそれを表示するためのものである．この関数は HTML 側から呼び出すために @eel.expose デコレータが直前（16 行目）に記述されている．HTML 側からこれを呼び出すには，‘eel.’ を関数呼出しの直前に記述する．これにより JavaScriptの関数と同じように呼び出すことができる．

JavaScript の関数を Python 側から呼び出すこともできる．この場合，JavaScript の関数の定義と共に，eel.expose
関数を用いて（ui02.html の 19 行目）Python 側から利用できるように設定しておく必要がある．
このアプリケーションでは，ui02.html の「現在時刻」ボタンをクリックすると，Python 側の関数 pyFun1 が呼び出される．この関数では，datetime モジュールにより現在時刻を求め，それを JavaScript の関数 jsFun2 に渡して

ui02.html のテキストフィールド（id=”t1”）の value 属性に設定する．これにより UI のテキストフィールドに時刻が表示される．

2.2.2.1関数の戻り値について

Python と JavaScript の間で関数を呼び出す際，引数に値を渡すことはできるが，通常の return による戻り値の受け渡しはできない．これは，Python 処理系と Web ブラウザが異なるプロセスとして実行されているため14 である．
今回のプログラムでは，Python 側の関数 pyFun1 が JavaScript 側の関数 jsFun2 を呼び出すことで，Python から

JavaScript に値を渡して，jsFun2 の動作としてテキストフィールド t1 に値を設定している．

14 参考） 異なるプロセスの間で値を受け渡しするには特別な方法が必要となる．

48

メディアデータの変換： PyDub

2.3

PyDub を用いることで，各種のメディアデータ（音声，動画）のフォーマットを変換することができる．PyDub はに関する情報は公式インターネットサイト

http://pydub.com/
から入手することができる．PyDub はメディアデータの変換に FFmpeg を用いており，利用に先立って FFmpeg 15
をインストールしておく必要がある．
ここでは，WAV 形式の音声データと MP3 形式の音声データの間の変換を例に挙げて，PyDub の基本的な使用方法について説明する．

2.3.1

音声ファイルの読込み

PyDub では音声データを AudioSegment クラスのオブジェクトとして扱う．このクラスを扱うためには次のようにして必要なものを Python 処理系に読み込む．

from pydub import AudioSegment
例．WAV 形式音声ファイル aaa.wav の読込み>>> from pydub import AudioSegment← AudioSegment クラスの読込みEnter>>> a = AudioSegment.from wav(’aaa.wav’)Enter←音声ファイルの読込み

この例では WAV 形式音声ファイル ‘aaa.wav’ の内容を from wav メソッドで読み込み，それを AudioSegment クラスのオブジェクト a にしている．MP3 形式の音声ファイルを読み込むには from mp3 メソッドで同様の処理を行う．

AudioSegment オブジェクトの重要なプロパティを表 14 に示す．
表 14: AudioSegment オブジェクトの重要なプロパティ
プロパティ

説明

sample width

量子化ビット長（バイト単位）

channels

チャンネル数

frame rate

サンプリング周波数（サンプリングレート：単位は Hz）

duration seconds

音声データの長さ（秒）例．AudioSegment オブジェクトのプロパティ（先の例の続き）>>> a.sample widthEnter←量子化ビット長（バイト単位）2← 2 バイト（16 ビット）>>> a.channels
2Enter←チャンネル数← 2 チャンネル（通常のステレオ音声）>>> a.frame rateEnter
←サンプリング周波数（サンプリングレート）
44100← 44.1KHz>>> a.duration seconds
0.40199546485260773
2.3.2

Enter
←長さ
←音声の再生時間（秒）音声データから NumPy の配列への変換

音声データを NumPy ライブラリを用いて解析するには，AudioSegment オブジェクトが持つ音声のデータ列を

NumPy 16 の配列データに変換する必要がある．そのためには次のような手順を踏む．
1. AudioSegment の音声データを get array of samples メソッドで取り出す．
2. それを NumPy の配列（ndarray）に変換する．
実際の処理の例を次に示す．
15 FFmpeg：メディアデータの変換のためのソフトウェア（https://ﬀmpeg.org/）
16 「3.1 数値計算と可視化のためのライブラリ：NumPy / matplotlib」（p.51）で解説する．

49

例．AudioSegment オブジェクトから NumPy の配列への変換（先の例の続き）

Enter>>> import numpy as np← NumPy の読込みEnter>>> ar = np.array(a.get array of samples())
Enter>>> ar.dtype
dtype(’int16’)>>> ar.shape(35456,)← AudioSegment から NumPy 配列への変換←データ形の調査← 2 バイト符号付き整数

Enter←配列の形状の調査← 35456 個の数値列

この例では，AudioSegment オブジェクト a が持つデータ列を，NumPy の配列オブジェクト ar に変換している．
データ列は 1 次元であるが，チャンネル数が 2（左右のステレオ音声）の場合は，各チャンネルのデータの格納順は「左, 右, 左, 右,…」となる．

2.3.3

NumPy の配列から音声データへの変換

NumPy ライブラリを用いると，数値としての音声データの列に対して様々な処理を施すことができる．あるいは任意の音声波形を合成することも容易である．NumPy の配列データを AudioSegment オブジェクトに変換すること
で，それを音声のデータファイルとして保存することができる．

NumPy の配列を AudioSegment オブジェクトに変換するには AudioSegment クラスのコンストラクタに各種のキー
ワード引数を指定して実行する．
例．NumPy の配列から AudioSegment オブジェクトを生成する（先の例の続き）>>> a2 = AudioSegment( data=ar, sample width=2, frame rate=44100, channels=2 )Enter

この例のように，NumPy の配列をキーワード引数 ‘data=’ に指定する．また，表 14 に示した各種プロパティと同名のキーワード引数があり，それらの値を設定することができる．

2.3.4
2.3.4.1

音声ファイルの保存

MP3 形式ファイルとして保存

AudioSegment オブジェクトの内容を音声データファイルとして保存するには export メソッドを使用する．このメ
ソッドの第一引数に保存先のファイル名（パス名）を与え，フォーマット名をキーワード引数 ‘format=’ に，再生ビットレートを ‘bitrate=’ に，変換処理プログラムに渡す引数並びを ‘parameters=’ に指定する．
例．AudioSegment オブジェクト a2 を MP3 形式ファイル ‘aaa.mp3’ として保存（先の例の続き）>>> a2.export(’aaa.mp3’,format=’mp3’,bitrate=’128k’,parameters=[’-cbr quality’,’10’]) Enter< io.BufferedRandom name=’aaa.mp3’>←保存処理中のメッセージ

この例では FFmpeg プログラムにエンコーディングの品質を指定する引数 ‘-cbr quality 10’ を渡しているが，‘parameters=’ は省略することができる．
2.3.4.2

WAV 形式ファイルとして保存

AudioSegment オブジェクトの内容を WAV 形式の音声ファイルとして保存する場合も export メソッドを使用する．
この場合はキーワード引数 ‘format=’ に ’wav’ を与える．
例．AudioSegment オブジェクト a2 を WAV 形式ファイル ‘aaa2.wav’ として保存（先の例の続き）>>> a2.export(’aaa2.wav’,format=’wav’)< io.BufferedRandom name=’aaa2.wav’>Enter←保存処理中のメッセージ

50

3

科学技術系

3.1

数値計算と可視化のためのライブラリ：NumPy / matplotlib

ここでは，数値計算のためのパッケージである NumPy と データを可視化するためのパッケージである matplotlib
に関して導入的に解説する．

NumPy は LAPACK（http://www.netlib.org/lapack/）や BLAS （http://www.openblas.net/）といった数値演算ラ
イブラリを使用して構築されており，大規模な配列データを処理するための機能を提供する．NumPy はオープンソースのソフトウェアであり，ソフトウェア本体やドキュメントなどが公式のインターネットサイト http://www.numpy.org/
で公開されている．

NumPy を使用するには次のようにしてモジュールを読み込む必要がある．
import numpy
あるいは，次のようにしてパッケージ名の別名を指定して読み込むことも慣例となっている．

import numpy as np
こうすることで，NumPy の各種関数やクラス，プロパティを ‘numpy.〜’ として記述する代わりに ‘np.〜’ として記述することができる．
（以後の説明ではこの慣例に従う）

3.1.1

NumPy で扱うデータ型

Python は動的な型付けの言語処理系であり，リストをはじめとするデータ構造の要素の型に制限はない．しかし
NumPy の処理は C 言語や FORTRAN などで実装された演算機能を含んでおり，扱うデータ列（配列）の要素の型は主として表 15 に挙げるようなもの17 である．
表 15: NumPy の代表的なデータ型
タイプ

意味

タイプ

意味

int8

符号付き 8 ビット整数

uint8

符号無し 8 ビット整数

int16

符号付き 16 ビット整数

uint16

符号無し 16 ビット整数

int32

符号付き 32 ビット整数

uint32

符号無し 32 ビット整数

int64

符号付き 64 ビット整数

uint64

符号無し 64 ビット整数

float16

16 ビット浮動小数点数

complex64

64 ビット複素数

float32

32 ビット浮動小数点数

complex128

128 ビット複素数

float64

64 ビット浮動小数点数

complex192

192 ビット複素数

float96

96 ビット浮動小数点数

complex256

256 ビット複素数

float128

128 ビット浮動小数点数

bool

真理値（True/False）※ 処理系によっては使えない型もあるので確認すること

表 15 に挙げたデータ型の配列に対する処理は，Python 元来のリストなどに対する処理と比較して非常に高速である．NumPy では ‘object’ という型も扱うことができ，異なる型の要素が混在する配列も作ることができる．ただしその場合は表 15 に挙げたデータ型の配列に比べると処理が遅く18 なる．

NumPy の複素数型（complex）の実部と虚部は共に浮動小数点数である．
3.1.2

配列オブジェクトの基本的な扱い方

NumPy では配列データ（データ列，行列）は array オブジェクト（データ型は ndarray）として扱う．array オブ
ジェクトのコンストラクタの引数に，配列データをリストで与えることができる．

17 他にも unicode（文字列型）や object （Python オブジェクト）といった型がある．
18 これに関しては「3.1.25.1 要素の型によって異なる計算速度」（p.138）で具体例を示す．

51

例．リストから NumPy の配列を生成する例>>> import numpy as np

Enter←パッケージを’np’ として読み込んでいる>>> lst = [1,2,3,4,5]

Enter←通常のリストの形でデータ列を生成>>> ar = np.array(lst)Enter← NumPy の配列に変換>>> ar←内容の確認Enter← NumPy の配列になっている

array([1, 2, 3, 4, 5])（p.123）で示すような方法（ゼロ行列の生成）で 2 次
この方法以外にも，後の「3.1.21.2 単位行列，ゼロ行列，他」元の配列を生成することができる．

3.1.2.1

配列の要素の型について

array オブジェクトのプロパティ dtype には，当該 array オブジェクトの要素の型が保持されている．
例．array の要素の型（先の例の続き）>>> ar.dtype

←型の調査

Enter

←要素の型は ’int32’ であることがわかる

dtype(’int32’)

array オブジェクトを生成する際，コンストラクタにキーワード引数

dtype=型 を与えることで要素の型を指定することができる．このときの型は表 15 のもの（パッケージ名. を先頭に付けたもの）を指定する．
例．型を指定した配列の生成>>> lst = [1,2,3,4,5]

Enter←通常のリストの形でデータ列を生成

Enter>>> ar = np.array(lst,dtype=np.float64)>>> ar←内容の確認Enter

array([ 1., 2., 3., 4., 5.])>>> ar.dtype← NumPy の配列に変換（ﬂoat64）

←型の調査

Enter

dtype(’float64’)←浮動小数点数（ﬂoat64）の要素を持つ NumPy の配列になっている←要素の型は ’ﬂoat64’ であることがわかる‘dtype=’ には型名を文字列で与えても良い．すなわち，
Enter>>> ar = np.array(lst,dtype=’float64’)← NumPy の配列に変換（ﬂoat64）

としても，同様の結果となる．
※ NumPy は複素数を扱うことができる．これに関しては「3.1.20 複素数の計算」（p.122）で解説する．

3.1.2.2

真理値の配列配列の生成の際にデータ型として ’bool’ を指定すると要素は真理値となる．
例．真理値の配列>>> lst = [True,False,False,True,False]>>> ar = np.array(lst1,dtype=’bool’)>>> ar

Enter

Enter

Enter

←真理値のリストを生成← NumPy の配列に変換←内容の確認←結果表示

array([ True, False, False, True, False])

この例における lst に数値のリストを与えることもできる．その場合は 0 を False，0 以外を True と解釈する．すな
わち，>>> lst = [2,0,0,-5,0]

Enter←数値のリストとしても，同様の結果となる．
真理値の配列は，配列同士を比較する際にも現れる．これに関しては後の「3.1.23 行列の検査」（p.134）でも説明
する．

52

3.1.2.3

基本的な計算処理

配列には算術演算（+，-，*，/ ）やべき乗（**）が実行できる．
例．配列同士の算術演算>>> a1 = np.array([1,3])Enter←配列 a1 を用意>>> a2 = np.array([2,4])Enter←配列 a2 を用意

Enter>>> a1 + a2

←計算結果

array([3, 7])Enter>>> a1 - a2

←和
←差
←計算結果

array([-1, -1])
Enter>>> a1 * a2

←積
←計算結果

array([ 2, 12])Enter>>> a1 / a2

←除算
←計算結果

array([0.5 , 0.75])

←べき乗

Enter

>>> a1 ** a2

array([ 1, 81], dtype=int32)←計算結果

この例からわかるように，配列同士の算術演算では，対応する要素の間の演算が行われ，それぞれの結果を要素とする配列が得られる．
次に，配列と数値（スカラー）との間の演算について説明する．
例．配列とスカラーとの間の演算（先の例の続き）>>> a1 + 4

Enter

←計算結果

array([5, 7])>>> a1 - 4←配列 a1 に 4 を加える

Enter

←配列 a1 から 4 を引く←計算結果

array([-3, -1])>>> a1 * 4Enter←配列 a1 を 4 倍する←計算結果

array([ 4, 12])>>> a1 / 4Enterarray([0.25, 0.75])>>> a2 ** 2Enter

←配列 a1 を 4 で割る←計算結果←配列 a2 を 2 乗する

array([ 4, 16], dtype=int32)←計算結果

このように，配列の各要素に対してスカラー値の演算を施す19 結果となる．
線形代数の演算に関しては後の「3.1.21 行列，ベクトルの計算（線形代数のための計算）」（p.123）で解説する．

NumPy は，Python 標準の math モジュールが提供する関数や定数と同じ名前のものを多く提供20 している．
例．pi，sin の値>>> np.pi

Enter← π （円周率）

3.141592653589793←値>>> np.sin( np.pi / 2 )

Enter

1.0

← sin

π
2

←値

NumPy が提供する数学関数は基本的に配列を扱うことができる．これを応用するとデータ集合に対する写像を簡単に実現することができる．

19 この機能はブロードキャストの一部．
20 詳しくは NumPy の公式インターネットサイト https://numpy.org/ を参照のこと．

53

例．データ集合に対する写像>>> X = np.array([0, np.pi/4, np.pi/2, np.pi*3/4, np.pi]) Enter ← [0, π/4, π/2, 3/4 ∗ π, π]←一度に sin の写像を作成

Enter>>> np.sin( X )array([0.00000000e+00, 7.07106781e-01, 1.00000000e+00, 7.07106781e-01,
1.22464680e-16])>>> X = np.array([0, 1, 4, 9, 16])>>> np.sqrt( X )←得られた写像←データ集合Enter←一度に平方根の写像を作成

Enter←得られた写像

array([0., 1., 2., 3., 4.])

この方法は，関数の可視化（プロット）の際にも応用できる．詳しくは「3.1.11 配列に対する演算：1 次元から 1 次元」（p.75）を参照のこと．

NumPy が提供する数学関数の多くは複素数を扱うことができる．
例．平方根の計算>>> np.sqrt( -2 )main :1:

Enter

RuntimeWarning:←√−2 を求める試み

invalid value encountered in sqrt

←戻り値は「非数」（後で説明する）

nan←引数を複素数にして>>> np.sqrt( -2+0j )Enter

1.4142135623730951j←複素数で計算結果が得られる√←警告メッセージ「不正な値」−2 を求めると平方根を求める関数 np.sqrt は，引数に複素数が与えられると複素数の戻り値を返す．

NumPy での複素数の扱いについては後の「3.1.20 複素数の計算」（p.122）で更に詳しく解説する．
3.1.2.4

扱える値の範囲

iinfo，ﬁnfo 関数を用いると配列の要素として扱える値の範囲を調べることができる．前者は整数値に関するもの，
後者は浮動小数点数に関するものである．
具体的には，これら関数の戻り値の min，max プロパティを参照する．
（表 16）

調査対象の型

表 16: 扱える値の範囲を調べる方法
最小値
最大値

整数

np.iinfo( 型名 ).min

np.iinfo( 型名 ).max

浮動小数点数np.ﬁnfo( 型名 ).min

np.ﬁnfo( 型名 ).max

例．扱える整数の範囲>>> print( ’int16:
int16:’, np.iinfo( ’int16’ ).min, ’〜’, np.iinfo( ’int16’ ).max )-32768 〜 32767←符号付き 16 ビット整数の範囲>>> print( ’uint16:’, np.iinfo( ’uint16’ ).min,’〜’, np.iinfo( ’uint16’ ).max )uint16:

0 〜 65535

Enter
Enter

←符号無し 16 ビット整数の範囲

例．扱える浮動小数点数の範囲>>> print(’float64:
float64:’,np.finfo( ’float64’ ).min, ’〜’,np.finfo( ’float64’ ).max ) Enter-1.7976931348623157e+308 〜 1.7976931348623157e+308← 64 ビット浮動小数点数の範囲>>> print(’complex128:’,np.finfo(’complex128’).min,’〜’,np.finfo(’complex128’).max)
complex128:-1.7976931348623157e+308 〜 1.7976931348623157e+308

複素数に関しては，実部と虚部の値の範囲が得られる．

3.1.2.5

特殊な値：無限大と非数

NumPy では表 17 にあるような無限大や非数を表す記号が定義されている．

54

Enter

← 128 ビット複素数の範囲

記号

意味

表 17: 特殊な数
記号
意味

inf

正の無限大

NINF

負の無限大
表示の際は ‘-inf’

記号

意味

nan

非数

※ -np.inf == np.NINF

例．無限大と非数← np.inf と非常に大きな数 1010000 の比較

Enter>>> np.inf > 10**10000← np.inf の方が大きい

True← np.NINF と非常に小さな数 −1010000 の比較

Enter>>> np.NINF < -10**10000← np.NINF の方が小さい

True← np.inf 同士の和Enter>>> np.inf + np.inf←正の無限大inf

Enter← np.NINF 同士の和Enter

←正負の異なる無限大同士の和Enter←無限大同士の除算>>> np.NINF + np.NINF←負の無限大-inf>>> np.inf + np.NINF
←非数

nan

>>> np.inf / np.inf
←非数

nan

注意）inf，nan はあくまで形式的なものであり，厳密な意味では数学的な値ではない．そのため，それらを値として数値計算に用いるべきではない．
■ 特殊な値かどうかの判定

NumPy は inf や nan といった特殊な値を判定する関数や有限の数値を判定する関数（下記）を提供している．
・ isinf( 値 )：値が正もしくは負の無限大なら True，それ以外なら False

・ isnan( 値 )：値が nan なら True，それ以外なら False

・ isﬁnite( 値 ) ：

値が有限の数値なら True，それ以外なら False

例．無限大かどうかの判定>>> np.isinf( np.inf )← np.inf を判定

Enter← np.NINF を判定←正の無限大True>>> np.isinf( np.NINF )←負の無限大True>>> np.isinf( 2 )Enter← 2 を判定←無限大ではない

False
3.1.2.6

Enter

データ列の生成（数列の生成）

range 関数に似た方法でデータ列を生成する関数として arange がある．
例．数列の生成>>> a = np.arange(0.0, 2.0, 0.1)
>>> a

Enter

Enter

← 0 以上 2 未満の範囲の数列を 0.1 刻みで生成←内容の確認array([ 0. , 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.
1.1, 1.2, 1.3, 1.4, 1.5, 1.6, 1.7, 1.8, 1.9]),←得られた数列

これとは別に，指定した区間を等分して n 個の要素から成る数列を得るには linspace 関数を使用する．

55

例． 区間 [n1 , n2 ]（n1 以上 n2 以下）を等分して 10 個のデータを得る← 0〜1 までを等分（最後の 1 を含む）

Enter>>> np.linspace( 0, 1.0, 10 )←得られた数列

array([ 0. , 0.11111111, 0.22222222, 0.33333333, 0.44444444,
0.55555556, 0.66666667, 0.77777778, 0.88888889, 1. ])このように最後の 1 を含んで 10 個のデータを得るため，結果的に 9 等分したものとなる．linspace 関数にキーワード
引数 ’endpoint=False’ を与えると最後の 1 を含まず，結果として 10 等分したデータを得ることができる．
例．10 等分した形でデータを得る

Enter>>> np.linspace( 0, 1.0, 10, endpoint=False )array([ 0.

← 0〜1 までを 10 等分, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9])←得られた数列

arange や linspace を使用して生成したデータ列は，NumPy の各種関数の定義域として与えることができ，値域のデータ列を得る目的に使用することができる．対数スケールで関数の定義域のデータ列を生成するには logspace を使用るのが良い．
例．20 〜210 の数列を対数スケールで 6 個の要素として生成>>> np.logspace( 0, 10, 6, base=2 )←対数スケール列生成Enter

array([ 1.00000000e+00, 4.00000000e+00, 1.60000000e+01,
6.40000000e+01, 2.56000000e+02, 1.02400000e+03])←得られた数列

キーワード引数 ’base=’ を省略すると 10 が基数となる．
例．100 〜1010 の数列を対数スケールで 6 個の要素として生成>>> np.logspace( 0, 10, 6 )Enter←対数スケール列生成

array([ 1.00000000e+00, 1.00000000e+02, 1.00000000e+04,
1.00000000e+06, 1.00000000e+08, 1.00000000e+10])
3.1.2.7←得られた数列

多次元配列の生成

多次元の配列もリストから生成することができる．
例．2 次元配列の生成>>> a2 = np.array([[1,2,3,4],[5,6,7,8]])>>> a2

Enter

Enter

← 2 次元配列（行列）の生成

←内容確認
←生成結果

array([[1, 2, 3, 4],[5, 6, 7, 8]])2 行 4 列の配列が得られている．

例．3 次元配列の生成（先の例の続き）>>> a3 = np.array([[[1,2],[3,4]],[[5,6],[7,8]]])>>> a3Enter← 3 次元配列の生成

←内容確認

Enter

array([[[1, 2],[3, 4]],←生成結果[[5, 6],[7, 8]]])
3.1.2.8配列の形状の調査

配列オブジェクトの shape プロパティに配列の各次元のサイズがタプルとして保持されている．
例．配列のサイズ（先の例の続き）>>> a2.shape(2, 4)

Enter← a2 のサイズを求める← 2 行 4 列である
← a3 のサイズを求める>>> a3.shapeEnter(2, 2, 2)← 3 次元配列（2 × 2 × 2）である

56

1 次元のデータ列からも shape は取得できる．
例．1 次元のデータ列のサイズ>>> a1.shape←データ列の生成Enter>>> a1 = np.array([1,2,3])← a1 のサイズを求める

Enter←タプルの形で得られる(3,)>>> a1.shape[0]←タプルの要素としてサイズを求める

Enter←長さが得られる（len(a1) としても同様）

3

配列オブジェクトの次元は ndim プロパティに保持されている．
例．配列の次元（先の例の続き）← a1 の次元を求める>>> a1.ndim

Enter

1

← 1 次元>>> a2.ndim

Enter

2

← 2 次元>>> a3.ndim

Enter

3

← 3 次元3.1.2.9← a2 の次元を求める← a3 の次元を求める

配列の要素へのアクセス

NumPy の配列の要素へのアクセスには，リストの場合と同様にスライス ‘[ ]’ が使用できる．また多次元の配列の要素にアクセスする場合には，スライス内にコンマ ‘,’ を記述して各次元の要素の格納位置を指定できる．
例．3 × 3 の配列の各要素へのアクセス>>> import numpy as np

...

...
>>> a

Enter

for k in range(3):...

←配列の各要素への値の設定（ここから）Enter

for j in range(3):...

← 3 × 3 の配列の生成21Enter>>> a = np.zeros( (3,3,3) )>>> for i in range(3):← NumPy モジュールの読込み

Enter

Enter

a[i,j,k] = 100*(i+1)+10*(j+1)+k+1
Enter

Enter

←スライス内をコンマで区切っている←（ここまで）←配列の内容の確認

Enter

array([[[111., 112., 113.],[121., 122., 123.],[131., 132., 133.]],[[211., 212., 213.],[221., 222., 223.],[231., 232., 233.]],[[311., 312., 313.],[321., 322., 323.],[331., 332., 333.]]])
3.1.2.10

スライスにデータ列を与えた場合の動作

NumPy の配列のスライスにデータ列を与えると，そのデータ列をインデックスの並びと見て元の配列の対応する要素を取り出し，それを配列として返す．
例．スライスにデータ列を与える例>>> a = np.array( [0,2,4,8,16,32,64,128,256,512,1024] )>>> idx = [0,2,4,6,8,10]>>> a[idx]

Enter

Enter

Enter

← 2n の配列←スライスに与えるインデックス n の並びを作成←要素を参照する

array([ 0, 4, 16, 64, 256, 1024])←結果

21 p.123「3.1.21.2 単位行列，ゼロ行列，他」で説明する．

57

3.1.2.11

指定した行，列へのアクセス（次の例参照）
リストのスライスに記述するように ‘:’ を用いると，指定した 1 つの行や列にアクセスできる．
例．先頭の行の取り出し>>> a = np.array( [[11,12,13],[21,22,23],[31,32,33]] )array([[11, 12, 13],
[21, 22, 23],
[31, 32, 33]])
Enter>>> a[0,:]← 2 次元の配列を用意

←内容確認

Enter

>>> a

Enter

←結果表示

←先頭行（第 0 番目の行）の取り出し←先頭行が 1 次元配列として得られている

array([11, 12, 13])

同様に，1 つの列を取り出す例を示す．
例．先頭の列の取り出し（先の例の続き）

Enter>>> a[:,0]←最初の列（第 0 番目の列）の取り出し←最初の列が 1 次元配列として得られている

array([11, 21, 31])

特定の行や列に対して 1 度に値を与えることができる．
例．指定した行や列に 1 度で値を設定する（先の例の続き）>>> a[1,:]= [101,102,103]

Enter

>>> a

←インデックス 1 番目の行にまとめて値を与える

Enter

←内容確認

array([[ 11, 12, 13],
←結果表示
[101, 102, 103],[ 31, 32, 33]])

Enter

>>> a

←インデックス 1 番目の列にまとめて値を与える

Enter>>> a[:,1] = [-1,-2,-3]←内容確認

array([[ 11, -1, 13],[101, -2, 103],[ 31, -3, 33]])←結果表示

この例では，行や列にリストで値を与えているが，配列の形で与えても良い．

3.1.2.12

配列形状の変形

配列を指定した次元の構造に変形するには reshape メソッドを使用する．
例．1 次元を 2 次元に変形>>> a = np.arange( 8 )
>>> a

Enter

← 1 次元配列

Enter

←内容確認
←結果表示

array([0, 1, 2, 3, 4, 5, 6, 7])>>> a2 = a.reshape( (2,4) )>>> a2

Enter

Enter

← 2 次元配列（2 行 4 列）に変形←内容確認

array([[0, 1, 2, 3],[4, 5, 6, 7]])

←結果表示

例．1 次元を 3 次元に変形（先の例の続き）>>> a3 = a.reshape( (2,2,2) )>>> a3Enter

array([[[0, 1],[2, 3]],

Enter← 3 次元配列（2 × 2 × 2）に変形

←内容確認
←結果表示

[[4, 5],[6, 7]]])

58

reshape の引数に与えるサイズ指定において負の値を与えると，行や列のサイズを NumPy が自動的に設定する．
例．行，列のサイズの自動設定（先の例の続き）←行数に-1 を与えて自動設定（4 列になるよう調整される）>>> a.reshape( (-1,4) )Enter

array([[0, 1, 2, 3],[4, 5, 6, 7]])

←結果表示>>> a.reshape( (2,-1) )Enter

array([[0, 1, 2, 3],[4, 5, 6, 7]])

←結果表示

←列数に-1 を与えて自動設定（2 行になるよう調整される）

多次元の配列を 1 次元に変形（平坦化）するには ﬂatten メソッドを使用する．
例．3 次元を 1 次元に変形（先の例の続き）← 1 次元に変形Enter>>> a3.flatten()array([0, 1, 2, 3, 4, 5, 6, 7])←結果表示

ﬂatten とは別に ravel，reshape といったメソッドでも配列を平坦化することができ，処理に要する時間は ﬂattenより短い．それぞれのメソッド毎に，配列の平坦化に要する時間を比較するプログラム ﬂatten01.py を示す．
プログラム：ﬂatten01.py
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

# coding : utf -8
import numpy as np
import timesz = 10000# 2次 元 配 列 の 作 成
m0 = np . arange (0 , sz **2)m = m0 . reshape (( sz , -1))
print ( ’2 次 元 配 列 の 形 状 : ’ , m . shape )# - - - f l a t t e n に よ る 平 坦 化 --t1 = time . time ()m1 = m . flatten ()t2 = time . time ()b = ( m0 == m1 ). all ()print ( ’ f l a t t e n の 所 要 時 間 :\ t ’ , t2 - t1 , ’\ t 検 証 結 果 : ’ , b )# - - - r a v e l に よ る 平 坦 化 --t1 = time . time ()m2 = m . ravel ()t2 = time . time ()b = ( m0 == m2 ). all ()print ( ’ r a v e l の 所 要 時 間 :\ t ’ , t2 - t1 , ’\ t 検 証 結 果 : ’ , b )# - - - r e s h a p e に よ る 平 坦 化 --t1 = time . time ()m3 = m . reshape ( -1)
t2 = time . time ()b = ( m0 == m3 ). all ()print ( ’ r e s h a p e の 所 要 時 間 :\ t ’ , t2 - t1 , ’\ t 検 証 結 果 : ’ , b )このプログラムにあるように reshape(-1)，ravel() を多次元の配列に対して実行する．
このプログラムを実行した様子を次に示す．
2 次元配列の形状:(10000, 10000)

flatten の所要時間:

0.08709502220153809

ravel の所要時間:

0.0

検証結果:

True

検証結果:

reshape の所要時間:

0.0

検証結果:

True

True

（使用した計算機環境：CPU Intel Core i7-6770HQ 2.6GHz，RAM 16GB，Windows 10）

ravel，reshape による平坦化の処理にはほとんど時間がかからないことがわかる．
59

3.1.2.13

行，列の転置

配列の行と列を転置するには T プロパティを参照する．
例．行，列の転置>>> a = np.array( [[1,2,3],[4,5,6]])
Enter

>>> a

←配列の作成←内容確認

array([[1, 2, 3],[4, 5, 6]])>>> a.T

Enter

←結果表示

←行と列の転置

Enter

←結果表示

array([[1, 4],[2, 5],[3, 6]])

この処理はプロパティの参照なので，元の配列には一切変更がない．

3.1.2.14

行，列の反転と回転

ﬂip 関数を使用すると行や列の反転ができる．
書き方：

ﬂip( 配列, axis=[1 か 0] )‘axis=0’ とすると縦方向（上下）の反転，‘axis=1’ とすると横方向（左右）の反転となる．
例．行，列の反転Enter>>> a = np.array([[1,2,3],[4,5,6],[7,8,9]])
>>> a

Enter

←配列の作成←内容確認

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

←結果表示>>> np.flip(a,axis=0)

Enter

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

←結果表示>>> np.flip(a,axis=1)

Enter

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

←結果表示

←縦方向（上下）の反転←横方向（左右）の反転

行，列を回転するには roll 関数を使用する．
書き方：

roll( 配列, shift=回転量, axis=[1 か 0] )「回転量」に負の値を与える
axis=0’ とすると縦方向（上下）の回転，‘axis=1’ とすると横方向（左右）の回転となる．
と，回転方向が逆になる．

60

例．行，列の回転

>>> a

Enter

←内容確認

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

←結果表示>>> np.roll(a,shift=1,axis=0)
array([[7, 8, 9],[1, 2, 3],[4, 5, 6]])array([[3, 1, 2],[6, 4, 5],[9, 7, 8]])Enter

←縦方向（上下）の回転

Enter←横方向（左右）の回転←結果表示>>> np.roll(a,shift=1,axis=1)

3.1.2.15←配列の作成Enter>>> a = np.array([[1,2,3],[4,5,6],[7,8,9]])

←結果表示

型の変換

配列の要素の型を変換するには astype メソッドを使用する．
例．要素の型の変換

>>> a

Enter

←’ﬂoat64’ 型の要素の配列

Enter>>> a = np.arange( 0, 10, dtype=’float64’ )←内容確認array([0., 1., 2., 3., 4., 5., 6., 7., 8., 9.])Enter>>> a.astype(np.int16)←結果表示（小数点が表示されている）←要素の型を ’int16’ に変換

array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9], dtype=int16)←整数として表示されているスカラー値の型の変換はnp. 型名 ( 値 )とする．
例．整数値を NumPy の int32 型に変換する>>> a = np.int32( 5 )
>>> a
5

Enter

← Python の通常の整数を変換

Enter

←内容確認

← Python の通常の整数に見えるが…

>>> type( a )Enter←型を調べると← NumPy の int32 型である

<class ’numpy.int32’>

例．NumPy の int32 型を ﬂoat64 型に変換する（先の例の続き）

Enter>>> b = np.float64( a )
>>> b
5.0

Enter

←内容確認

← Python の通常の浮動小数点数（ﬂoat）に見えるが…

>>> type( b )Enter<class ’numpy.float64’>
3.1.2.16←先の int32 型の数を変換←型を調べると← NumPy の ﬂoat64 型である配列の複製（コピー）

配列を複製するには copy 関数（あるいは copy メソッド）を使用する．これに関して段階的に例を挙げて説明する．

61

例．配列を変数記号に割り当てるEnter>>> a = np.array([[1,2],[3,4]])
>>> a

Enter

←変数 a の値の確認←変数 a の内容

array([[1, 2],[3, 4]])>>> b = a>>> b

←変数 a が指し示す配列を変数 b に割り当てる

Enter

Enter

←配列を作成して変数 a に割り当てる←変数 b の値の確認←変数 b の内容

array([[1, 2],[3, 4]])

次に，a の配列の変更を試みる．
例．変数 a に割り当てられた配列の内容を変更する（先の例の続き）

>>> a

Enter

←変数 a の内容を確認←変数 a の内容

array([[1, 2],[5, 6]])
>>> b

Enter

←変数 a の配列の内容を変更

Enter>>> a[1,0] = 5; a[1,1] = 6←変数 b の内容を確認すると…
←こちらも変更されている

array([[1, 2],[5, 6]])

この例からもわかる通り，ある変数に割り当てられた配列を別の変数に ‘=’ で割り当てた場合，初めの変数に割り当てた配列と，後の変数に割り当てた配列は同一のものである．
既存の配列の複製（コピー）を別の配列として作成するには copy 関数を使用する．
例．配列の複製（先の例の続き）

>>> c

Enter

←変数 c の内容を確認←変数 a と同じ内容

array([[1, 2],[5, 6]])>>> a[1,0] = 3; a[1,1] = 4
>>> a

Enter

Enter

←変数 a の配列の内容を変更

Enter←変数 a の値の確認←変数 a の内容

array([[1, 2],[3, 4]])>>> c←変数 a の配列の複製を変数 c に与える

Enter>>> c = np.copy( a )←変数 c の内容は…
←変数 a に対する編集の影響がない

array([[1, 2],
Enter[5, 6]])
この例の最初の部分を

c = a.copy()
として，メソッドの形で copy を実行することもできる．

3.1.3
3.1.3.1

配列の連結と繰り返し

append，concatenate による連結

例．append による配列の連結>>> a = np.array([1,2])Enter←配列の生成 (1)>>> b = np.array([3,4])Enter←配列の生成 (2)>>> np.append(a,b)

Enter←上記 2 つの配列の連結

array([1, 2, 3, 4])←連結結果>>> np.append(a,[5,6])Enter

array([1, 2, 5, 6])←配列にリストを連結←連結結果は配列として得られる

62

append 関数は連結結果を新たな配列として返す．また多次元配列の連結もできる．
例．2 次元の配列同士の連結>>> a = np.array([[1,2],[3,4]])Enter← 2 次元配列の生成 (1)>>> b = np.array([[5,6],[7,8]])Enter← 2 次元配列の生成 (2)>>> np.append(a,b,axis=0)
array([[1, 2],[3, 4],[5, 6],[7, 8]])←新たな行として連結Enter←連結結果（行の追加）>>> np.append(a,b,axis=1)
array([[1, 2, 5, 6],[3, 4, 7, 8]])

←新たな列として連結Enter←連結結果（列の追加）

この例のように，行として連結する場合は append 関数にキーワード引数 ‘axis=0’ を，列として連結する場合は ‘axis=1’を与える．
複数の配列を連結する場合は concatenate 関数を用いる．
例．複数の配列の連結 (1 次元同士)>>> a1 = np.array([0,1]); a2 = np.array([2,3]); a3 = np.array([4,5])Enter↑ 3 つの 1 次元配列を用意>>> ac = np.concatenate( [a1,a2,a3] )>>> ac

Enter

←全て連結

←内容確認

Enter

←結果表示

array([0, 1, 2, 3, 4, 5])
例．複数の配列の連結 (2 次元同士)>>> a = np.array([[0,1],[2,3]])Enter>>> b = np.array([[4,5],[6,7]])Enter← 2 次元配列を 3 つ用意Enter>>> c = np.array([[8,9],[10,11]])>>> np.concatenate( [a,b,c], axis=0 )Enter←行方向に連結Enter←列方向に連結array([[ 0, 1],←連結結果[ 2, 3],[ 4, 5],[ 6, 7],[ 8, 9],[10, 11]])>>> np.concatenate( [a,b,c], axis=1 )array([[ 0, 1, 4, 5, 8, 9],←連結結果[ 2, 3, 6, 7, 10, 11]])3.1.3.2

hstack，vstack による連結

水平方向（列方向）に配列を連結する hstack 関数と，垂直方向（行方向）に配列を連結する vstack 関数がある．
例．hstack,vstack による配列の連結（2 次元）>>> a = np.array([[0,1],[2,3]])Enter←配列を用意>>> b = np.array([[4,5],[6,7]])Enter←配列を用意← hstack で連結>>> np.hstack( (a,b) )Enterarray([[0, 1, 4, 5],[2, 3, 6, 7]])

←連結結果>>> np.vstack( (a,b) )Enterarray([[0, 1],[2, 3],[4, 5],[6, 7]])← vstack で連結

←連結結果

63

これら関数によって 1 次元配列同士を連結すると次のようになる．
例．hstack,vstack による 1 次元配列同士の連結>>> a = np.array([0,1])Enter← 1 次元配列を用意>>> b = np.array([2,3])Enter← 1 次元配列を用意>>> np.hstack( (a,b) )Enter← hstack で連結

array([0, 1, 2, 3])>>> np.vstack( (a,b) )array([[0, 1],[2, 3]])←連結結果（単純な連結）← vstack で連結Enter←連結結果（2 次元になる）

参考）配列の連結にはこれ等の他にも ‘c ’，‘r ’ といった関数も存在するが，本書では割愛する．

3.1.3.3

tile による配列の繰り返し

tile 関数を使用すると，与えた配列を繰り返した形の配列を作成することができる．
書き方：

tile( 配列, (縦の繰り返し回数, 横の繰り返し回数) )例．配列の繰り返し>>> a = np.array([[1,2],[3,4]])
>>> a

Enter

array([[1, 2],[3, 4]])

←内容確認
←結果表示

>>> np.tile( a, (2,3) )←配列 a を縦に 2 回，横に 3 回繰り返す

Enter

array([[1, 2, 1, 2, 1, 2],[3, 4, 3, 4, 3, 4],[1, 2, 1, 2, 1, 2],[3, 4, 3, 4, 3, 4]])3.1.4

←配列を用意

Enter

←結果表示

配列への要素の挿入

insert を使用することで，配列の指定した位置に要素を挿入することができる．insert の第 1 引数には対象となる配列を，第 2 引数には挿入位置（インデックス）を，第 3 引数には挿入する値を与える．
例．1 次元配列への要素の挿入>>> a = np.array([0,1,2,3,4,5])>>> a2 = np.insert( a, 2, 9 )>>> a2Enter←配列を用意

Enter
Enter

←インデックスが 2 の位置に 9 を挿入←内容確認

array([0, 1, 9, 2, 3, 4, 5])←結果表示

このように insert は挿入処理の結果の配列を返す．元の配列は変化しない．挿入位置として指定できるのは 0 から
「配列の末尾のインデックス+1」までである．それより大きな値を指定するとエラーとなる．
参考）insert の第 3 引数には配列（ndarray）を与えても良い．

insert は複数の値を挿入することができる．
例．複数の要素の挿入（先の例の続き）>>> np.insert( a, 3, [7,8,9] )Enter

array([0, 1, 2, 7, 8, 9, 3, 4, 5])←インデックスが 3 の位置に [7,8,9] を挿入←挿入結果

これは，インデックスが 3 の位置に複数の値を挿入する例である．これとは別に，挿入位置を複数指定して，個別に値を挿入することもできる．
（次の例参照）

64

例．複数の挿入位置に個別に要素を挿入（先の例の続き）←挿入位置を複数指定>>> np.insert( a, [3,4,5], [7,8,9] )Enter

array([0, 1, 2, 7, 3, 8, 4, 9, 5])←挿入結果

この例からわかるように，挿入位置は元の配列を基準にした形で指定する．

3.1.4.1

行，列の挿入insert の第 4 引数に ‘axis=0’ を与えると，2 次元配列の指定した位置に行を挿入することができる．
例．行の挿入Enter>>> a = np.array( [[11,12,13,14],[21,22,23,24],
...
>>> a

←配列を用意[31,32,33,34],[41,42,43,44]] )
Enter

←内容確認

array([[11, 12, 13, 14],
[21, 22, 23, 24],
[31, 32, 33, 34],
[41, 42, 43, 44]])

←内容表示

Enter

>>> np.insert( a, 1, [91,92,93,94], axis=0 )array([[11, 12, 13, 14],[91, 92, 93, 94],
[21, 22, 23, 24],
[31, 32, 33, 34],
[41, 42, 43, 44]])←インデックス位置 1 に行を挿入←挿入結果

複数の行を挿入することもできる．
例．複数行の挿入（先の例の続き）

Enter>>> i1 = [[71,72,73,74],[81,82,83,84]]>>> np.insert( a, 1, i1, axis=0 )array([[11, 12, 13, 14],[71, 72, 73, 74],
[81, 82, 83, 84],
[21, 22, 23, 24],
[31, 32, 33, 34],
[41, 42, 43, 44]])←挿入する複数の行を用意←インデックス位置 1 に行を挿入

Enter

←挿入結果

挿入位置を複数指定することもできる．
例．挿入位置を複数指定（先の例の続き）>>> np.insert( a, [1,3], i1, axis=0 )array([[11, 12, 13, 14],[71, 72, 73, 74],
[21, 22, 23, 24],
[31, 32, 33, 34],
[81, 82, 83, 84],
[41, 42, 43, 44]])Enter←インデックス 1,3 の位置に挿入←挿入結果

insert の第 4 引数に ‘axis=1’ を与えると，2 次元配列の指定した位置に列を挿入することができる．
例．列の挿入（先の例の続き）>>> np.insert( a, 2, [63,73,83,93], axis=1 )array([[11, 12, 63, 13, 14],
[21, 22, 73, 23, 24],
[31, 32, 83, 33, 34],
[41, 42, 93, 43, 44]])←挿入結果

複数の列を挿入することもできる．

65

Enter

←インデックス位置 2 に列を挿入

例．複数の列の挿入（先の例の続き）

Enter>>> i2 = [[63,73,83,93],[64,74,84,94]]←挿入する複数の列を用意（行形式）←インデックス位置 1 に列を挿入>>> np.insert( a, 1, i2, axis=1 )Enter

array([[11, 63, 64, 12, 13, 14],
[21, 73, 74, 22, 23, 24],
[31, 83, 84, 32, 33, 34],
[41, 93, 94, 42, 43, 44]])←挿入結果

これは，insert の第 2 引数にスカラー値（整数値）を与える場合である．次に複数の列位置に列を挿入する場合について説明する．
例．列の挿入位置を複数指定する（先の例の続き）>>> np.insert( a, [1,3], np.array(i2).T, axis=1 ) Enter←インデックス 1,3 の列位置に挿入←挿入結果

array([[11, 63, 12, 13, 64, 14],
[21, 73, 22, 23, 74, 24],
[31, 83, 32, 33, 84, 34],
[41, 93, 42, 43, 94, 44]])

この例では insert の第 3 引数に挿入するデータを与える際に，転置処理して「2 列の配列」に変換して与えている．
このように，挿入位置として非スカラーのもの（リストなど）を与える際は，挿入するデータも元の配列と同じ行数の形式に変換する必要がある．

3.1.5

配列要素の部分的削除

delete を使用することで，配列要素を部分的に削除することができる．delete の第 1 引数には対象となる配列を，第2 引数には削除位置（インデックス）を与える．
例．1 次元配列の要素の削除

Enter>>> a2 = np.delete( a, 3 )>>> a2Enter←配列を用意Enter>>> a = np.array([0,1,2,3,4,5])←インデックス位置 3 の要素を削除←内容確認

array([0, 1, 2, 4, 5])←結果表示

このように delete は削除結果の配列を返す．元の配列は変化しない．要素が存在しないインデックス位置を指定するとエラーとなる．
削除対象のインデックスは複数与えることができる．
例．複数の要素の削除（先の例の続き）>>> np.delete( a, [0,2,4] )array([1, 3, 5])Enter←インデックス位置 0,2,4 の要素を削除←削除結果

delete の第 2 要素に削除対象インデックスをリストにして与えている．
3.1.5.1

区間を指定した削除

delete の第 2 引数にスライスオブジェクト22 を与えることで，指定した区間の要素を全て削除することができる．
書き方：

delete( 配列, slice(n1 , n2 ) )このように記述することで n1 〜 n2 − 1 の区間の要素が削除される．
例．区間の削除（先の例の続き）>>> np.delete( a, slice(1,5) )array([0, 5])Enter←インデックス位置 1〜(5-1) の区間を削除←削除結果

これは a[1:5] に相当する部分を削除したことになる．
22 データ列の位置を表現するための特殊なオブジェクト．slice(…) のように記述する．

66

行，列の削除

3.1.5.2

delete の第 3 引数に ‘axis=0’ を与えると，2 次元配列の指定した行を削除することができる．
例．行の削除>>> a = np.array( [[11,12,13,14],[21,22,23,24],
...

Enter

←配列を用意[31,32,33,34],[41,42,43,44]] )

>>> a

←内容確認

Enter

←内容表示

array([[11, 12, 13, 14],
[21, 22, 23, 24],
[31, 32, 33, 34],
[41, 42, 43, 44]])←インデックス位置 1 の行を削除

Enter>>> np.delete( a, 1, axis=0 )←削除結果

array([[11, 12, 13, 14],[31, 32, 33, 34],
[41, 42, 43, 44]])delete の第 2 引数にはリストやスライスオブジェクトを与えて，複数の行を削除することができる．
delete の第 3 引数に ‘axis=1’ を与えると，2 次元配列の指定した列を削除することができる．
例．列の削除（先の例の続き）←インデックス位置 1 の列を削除

Enter>>> np.delete( a, 1, axis=1 )←削除結果

array([[11, 13, 14],
[21, 23, 24],
[31, 33, 34],
[41, 43, 44]])delete の第 2 引数にはリストやスライスオブジェクトを与えて，複数の列を削除することができる．
3.1.6

配列の次元の拡大

newaxis オブジェクトによる方法

3.1.6.1

newaxis オブジェクト（接頭辞を付けて np.newaxis）を用いて配列のスライス（添字）を追加することができる．
その結果として配列の次元が拡大される．
例．1 次元の配列を 2 次元に拡大（その 1）>>> a = np.array([0,1,2])← 3 つの要素を持つ 1 次元配列である(3,)>>> a2 = a[ np.newaxis, :>>> a2← 1 次元配列の作成←形状の確認Enter>>> a.shape

Enter

]

Enter

← a のスライス（添字）を 1 つ増やすことで次元を拡大

←内容確認

Enter

←結果表示

array([[0, 1, 2]])←形状の確認>>> a2.shapeEnter(1, 3)← 1 行 3 列のサイズの 2 次元配列である

この例で最初に作成した配列 a は，スライス付きの表現で a[:] と記述することでその全体を表すことができる．この表記に則ってa[ np.newaxis, :]と記述することでスライスが新たに 1 つ追加されることになる．このようにして拡大された配列 a2 は 2 次元配列となる．
（次の例参照）

67

例．2 次元配列 a2 に別の 2 次元配列を行の方向に連結（先の例の続き）←行の方向に追加

Enter>>> np.append(a2,[[3,4,5]],axis=0)←連結処理の結果

array([[0, 1, 2],[3, 4, 5]])

np.newaxis はスライスの任意の位置に挿入できる．
例．1 次元の配列を 2 次元に拡大（その 2：先の例の続き）← a のスライス（添字）を 1 つ増やすことで次元を拡大

Enter>>> a3 = a[ :, np.newaxis ]←形状の確認>>> a3.shapeEnter(3, 1)← 3 行 1 列のサイズの 2 次元配列である>>> a3Enter

array([[0],
[1],
[2]])

←内容確認
←結果表示

例．2 次元配列 a3 に別の 2 次元配列を列の方向に連結（先の例の続き）>>> np.append(a3,[[3],[4],[5]],axis=1)
array([[0, 3],[1, 4],[2, 5]])
3.1.6.2Enter←列の方向に追加←連結処理の結果

expand dims による方法

newaxis オブジェクトによる方法とは別に，expand dims 関数を用いて配列の次元を拡大することもできる．
例．1 次元の配列を 2 次元に拡大（その 1）

Enter>>> a = np.array([0,1,2])>>> a2 = np.expand dims( a, axis=0 )>>> a2Enter

array([[0, 1, 2]])

← 1 次元配列の作成← a の先頭の次元を 1 つ増やす

Enter

←内容確認
←結果表示

例．1 次元の配列を 2 次元に拡大（その 2：先の例の続き）>>> a3 = np.expand dims( a, axis=1 )>>> a3Enter

array([[0],
[1],
[2]])

← a の末尾の次元を 1 つ増やす

Enter

←内容確認
←結果表示

※ newaxis オブジェクトによる方法は expand dims による方法に比べて，より柔軟である．

3.1.7

データの抽出

データ列の中から指定した要素を抽出する方法について説明する．

3.1.7.1

真理値列によるマスキング

配列のスライスに真理値の配列を与えることで要素の抽出ができる．この場合，与えた真理値列の要素が True である位置に対応する要素を抽出する．

68

例．真理値列によるマスキング>>> import numpy as np

Enter←モジュールの読込み>>> a = np.arange(10)Enter← 0〜9 の整数列の生成

←内容確認

Enter

>>> a

←結果表示

array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])>>> msk = [True,False,True,False,True,False,False,False,False,False] Enter ←真理値列の作成← msk の要素が True である位置に対応する要素の抽出（マスキング）Enter>>> a[ msk ]array([0, 2, 4])←抽出結果

マスキングに用いる真理値列は ndarray でも良い．

3.1.7.2

条件式による要素の抽出

条件式から真理値列を生成することもできる．これを応用して配列の要素を抽出する例を示す．
例．条件式から真理値列を生成（先の例の続き）>>> a%2==0

Enter←条件から真理値列を生成

array([ True, False, True, False, True, False, True,
False, True, False ])>>> a[ a%2==0 ]Enter

array([0, 2, 4, 6, 8])
3.1.7.3←結果←スライスに条件式を与える（真理値列を与えたことになる）←抽出結果

論理演算子による条件式の結合条件式の否定や，複数の条件式を結合（連言，選言）した複雑な条件による要素の抽出ができる．条件式の結合や否定は表 18 のような記述による．
表 18: 条件式の結合や否定のための演算子
記述

解説

p1 & p2

条件式 p1, p2 がともに真の場合に真，それ以外は偽となる．

p1 | p2

条件式 p1, p2 の両方もしくはどちらかが真の場合に真，両方とも偽の場合は偽となる．

~p

条件式 p が偽の場合に真，真の場合に偽となる．

例．条件式から真理値列を生成（先の例の続き）>>> a[ (a%2==0) & (a>5) ]array([6, 8])

Enter←連言（and）による条件式の結合Enter←否定と連言（and）による結合Enter←選言（or）による条件式の結合←結果>>> a[ ~(a%2==0) & (a>5) ]array([7, 9])←結果>>> a[ (a%2==0) | (a>5) ]array([0, 2, 4, 6, 7, 8, 9])←結果指定した条件を満たす要素を取り出すには，次に説明する where が便利である．

3.1.7.4

where による要素の抽出と置換配列を用いて記述した条件式を where 関数に与えると，その条件を満たす要素の配列（あるいはそのタプル）を返す．
書き方 1：

where( 条件式 )69

例．where による要素の抽出>>> a← 0〜9 の配列を作成

Enter>>> a = np.array( range(10) )
←内容確認

Enter

←結果

array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])← 5 より大きな要素を抽出する

Enter>>> np.where( a > 5 )←結果（配列のタプル）(array([6, 7, 8, 9], dtype=int64),)Enter>>> np.where( a > 5 )[0]array([6, 7, 8, 9], dtype=int64)
書き方 2：← 5 より大きな要素の抽出（タプルの先頭部分）←結果（配列）where( 条件式, 真の場合の値, 偽の場合の値 )この書き方を用いると，条件に基づく配列の要素の置換ができる．
例．条件に基づく要素の置換（先の例の続き）← 5 以上の要素のみ 10 倍する処理Enter>>> np.where( a<5, a, 10*a )array([ 0, 1, 2, 3, 4, 50, 60, 70, 80, 90])

←結果（配列）

この処理は多次元の配列に対しても実行できる．
例．多次元配列に対する where（先の例の続き）

Enter>>> a = np.identity( 3 )
>>> a

←内容確認

Enter

array([[1., 0., 0.],[0., 1., 0.],[0., 0., 1.]])←結果>>> np.where( a==1, 4, 2 )Enter← 1 の要素を 4 に，それ以外を 2 に置き換える処理←結果

array([[4, 2, 2],[2, 4, 2],[2, 2, 4]])3.1.7.5← 3 次元の単位行列23

最大値，最小値，その位置の探索

配列の要素の最大値，最小値はそれぞれ max，min メソッドで求めることができる．
例．最大値，最小値>>> a = np.array([2,4,6,8,10,8,6,4,2,4,6,8,10])>>> a.max()
10←最大値を求めるEnter←最小値を求める←サンプルデータ←結果>>> a.min()
2

Enter

Enter

←結果

最大値，最小値が最初に現れる位置（インデックス値）を argmax ，argmin で調べることができる．
例．最大値，最小値の位置>>> a.argmax()
4

Enter

←最初の最大値の位置（インデックス値）を求める←結果（インデックスの 4 番目）>>> a.argmin()0（先の例の続き）

Enter←最初の最小値の位置（インデックス値）を求める←結果（インデックスの 0 番目）■ 2 次元配列に対する max，min，argmax，argmin

2 次元配列に対する max，min，argmax，argmin の動作について例を挙げて説明する．

23 「3.1.21.2 単位行列，ゼロ行列，他」（p.123）で解説する．

70

例．2 次元配列に対する max，argmax>>> a0 = np.array([[1,5,9],[2,6,7],[3,4,8]])>>> a0.max()
9← 2 次元のサンプルデータ←最初の最大値

Enter

←結果

>>> np.argmax( a0 )
2

Enter

←最初の最大値の位置（インデックス値）を求める

Enter

←結果

このように，与えられた配列を 1 次元に平坦化した場合の最大値，そのインデックス位置を返す．また max，argmaxの引数にキーワード引数 ‘axis=’ を与えると「各列の最大値」，「各行の最大値」に関する値を返す．
例．キーワード引数 ‘axis=0’ を与えた場合（先の例の続き）>>> print( a0 )← 2 次元表示で確認Enter[[1 5 9][2 6 7][3 4 8]]>>> a0.max( axis=0 )←各列の最大値を求める

Enter

←結果

array([3, 6, 9])>>> np.argmax( a0, axis=0 )←各列の最大値の位置を求める

Enter

←結果

array([2, 1, 0], dtype=int64)
この例の動作の解釈を図 33 に示す．

[[ 1

5

9 ]

[ 2

6

7 ]

[ 3

4

8 ]]

最大：インデックス 2
最大：インデックス 1
最大：インデックス 0

図 33: 各列の最大値の考え方
例．キーワード引数 ‘axis=1’ を与えた場合>>> a1 = np.array([[3,2,1],[4,6,5],[8,7,9]])>>> print( a1 )Enter

← 2 次元のサンプルデータ← 2 次元表示で確認Enter[[3 2 1]
[4 6 5][8 7 9]]>>> a1.max( axis=1 )array([3, 6, 9])←各行の最大値を求める

Enter

←結果

>>> np.argmax( a1, axis=1 )←各行の最大値の位置を求める

Enter

←結果

array([0, 1, 2], dtype=int64)
この例の動作の解釈を図 34 に示す．

[[ 3

2

1 ]

最大：インデックス 0

[ 4

6

5 ]

最大：インデックス 1[ 8

79 ]] 最大：インデックス 2

図 34: 各行の最大値の考え方

min，argmin に関しても同様に，キーワード引数 ‘axis=’ によって「列ごと」「行ごと」の処理ができる．

71

3.1.8

データの整列（ソート）sort 関数（あるいは sort メソッド）を使用すると配列の要素を整列（昇順）することができる．

sort 関数：sort( 整列対象の配列 )「整列対象の配列」を整列した結果の配列を返す．元の配列は変更しない．

sort メソッド： 整列対象の配列.sort()「整列対象の配列」そのものに整列処理を施す．値は返さない．

例．1 次元配列の整列>>> a = np.array( [3,5,1,4,2,6] )>>> np.sort(a)← sort 関数による整列の実行

Enter

array([1, 2, 3, 4, 5, 6])
>>> a

Enter

>>> a

Enter

←整列結果

←元の配列の内容確認

array([3, 5, 1, 4, 2, 6])>>> a.sort()←乱雑な順序の配列

Enter

Enter

←変化無し

← sort メソッドによる整列の実行←元の配列の内容確認

array([1, 2, 3, 4, 5, 6])←整列されている

例．降順に整列>>> a = np.array( [3,5,1,4,2,6] )>>> np.sort(a)[::-1]Enter

array([6, 5, 4, 3, 2, 1])
3.1.8.1

Enter←乱雑な順序の配列（先の例と同じ）← sort 関数による整列の後，スライスの工夫で逆順にしている←整列結果（降順）

2 次元配列の整列

2 次元配列に対して行方向，あるいは列方向を指定して整列ができる．サンプルとして次のような 2 次元配列を用意する．
例．2 次元配列のサンプル>>> a = np.array([[1,2,10],[300,3,100],[30,200,20]])
>>> a

Enter

Enter

← 2 次元配列の作成←内容確認

array([[ 1, 2, 10],[300, 3, 100],[ 30, 200, 20]])← 2 次元になっている

この配列 a に対して sort 関数を実行する．
例．2 次元配列の整列>>> np.sort(a,axis=0)

Enter

array([[ 1, 2, 10],
[ 30, 3, 20],[300, 200, 100]])>>> np.sort(a,axis=1)

Enter

array([[ 1, 2, 10],
[ 3, 100, 300],[ 20, 30, 200]])←縦方向の整列（列毎の整列）←縦方向に整列されている←横方向の整列（行毎の整列）←横方向に整列されている

この例のように sort 関数にキーワード引数 ‘axis=’ を与えることで整列の方向を制御できる．‘axis=0’ が縦方向，‘axis=1’（暗黙値）が横方向の整列を意味する．sort メソッドの場合も同様のキーワード引数を与えることができる．

72

3.1.8.2

整列結果のインデックスを取得する方法

argsort 関数（あるいは argsort メソッド）を使用すると配列の要素を整列（昇順）した際のインデックスの並びを返す．結果として得られるインデックスの配列の要素は元の配列に対する位置を意味する．
例．整列結果のインデックスの並びを取得する>>> np.argsort(a)← argsort 関数の実行

Enter←整列結果の要素のインデックス並びが得られている

array([2, 4, 0, 3, 1, 5], dtype=int64)← argsort メソッドの実行

Enter>>> a.argsort()←同様の結果となる

array([2, 4, 0, 3, 1, 5], dtype=int64)
>>> a

Enter

←乱雑な順序の配列

Enter>>> a = np.array( [3,5,1,4,2,6] )←元の配列の内容確認←変化無し

array([3, 5, 1, 4, 2, 6])

この処理は元の配列を変更しない．この処理の解釈を図 35 に示す．

0

元の列のインデックス
1

2

3

4

5

[3 5 1 4 2 6]

整列前の配列[1 2 3 4 5 6]

整列後の配列

2

4

0

3

1

5

argsort で得られた列

図 35: argsort の処理

argsort は 2 次元の配列に対しても使用できる．
例．2 次元配列に対する argsort>>> a = np.array([[1,2,10],[300,3,100],[30,200,20]])
>>> a

Enter

Enter

← 2 次元配列の作成←内容確認

array([[ 1, 2,[300, 3,
[ 30, 200,

10],
100],
20]])

>>> a.argsort(axis=0)← 2 次元になっている

Enter←縦方向の整列

array([[0, 0, 0],←インデックスの配列が得られている[2, 1, 2],[1, 2, 1]], dtype=int64)>>> a.argsort(axis=1)

Enter←横方向の整列

array([[0, 1, 2],←インデックスの配列が得られている[1, 2, 0],[2, 0, 1]], dtype=int64)
3.1.9

配列要素の差分の配列

diﬀ 関数を使用すると配列要素間の差分を配列として取得できる．
書き方：

diﬀ( 配列, 差分の階数 )第 2 引数を省略すると 1 階の差分が得られる．例を挙げてこの関数について解説する．

73

例．サンプルデータ>>> a = np.arange(0,8,1)>>> a3 = a**3>>> a3

Enter

Enter

Enter

array([ 0, 1, 8, 27, 64, 125, 216, 343], dtype=int32)←これをサンプルデータとする

このようにして得られた配列 a3 の差分を取る処理を次に示す．
例．配列の差分の配列を得る（先の例の続き）← 1 階の差分を求める

Enter>>> np.diff(a3)←結果

array([ 1, 7, 19, 37, 61, 91, 127], dtype=int32)>>> np.diff(a3,2)← 2 階の差分を求める

Enter

←結果

array([ 6, 12, 18, 24, 30, 36], dtype=int32)>>> np.diff(a3,3)← 3 階の差分を求める

Enter

array([6, 6, 6, 6, 6], dtype=int32)>>> np.diff(a3,4)←結果← 4 階の差分を求める

Enter

array([0, 0, 0, 0], dtype=int32)←結果

この例で行った処理を図 36 に示す．

図 36: 配列の差分

3.1.10配列に対する様々な処理

3.1.10.1

重複する要素の排除

unique 関数を使用すると，配列から重複する要素を排除することができる．
例．配列の中の重複する要素を排除する>>> a = np.array([2,6,7,5,2,7,5,7,3,8,1,9,1,4,8,4,6,9,3]) Enter
>>> a

Enter

←重複する要素を持つ配列←内容確認

array([2, 6, 7, 5, 2, 7, 5, 7, 3, 8, 1, 9, 1, 4, 8, 4, 6, 9, 3])>>> np.unique(a)Enter←重複要素の排除

array([1, 2, 3, 4, 5, 6, 7, 8, 9])←処理結果

処理結果は整列済みの形で得られる．また，元の配列の内容は変更されない．

3.1.10.2

要素の個数の集計

unique にキーワード引数 ‘return counts=True’ を与えると，要素毎の出現回数を求めることができる．
例．要素の個数の集計（先の例の続き）

Enter>>> (u,c) = np.unique(a,return counts=True)
>>> u

Enter

←戻り値の第 1 要素の内容確認

array([1, 2, 3, 4, 5, 6, 7, 8, 9])
>>> c

Enter

←要素数の集計←要素の配列←戻り値の第 2 要素の内容確認

array([2, 2, 2, 2, 2, 2, 3, 2, 2], dtype=int64)←上記の要素に対応する出現回数の配列

この例の場合は unique はタプルを返す．戻り値のタプルの第 1 要素は「唯一の要素」の配列（先の例と同じ），第 274

要素は要素毎の出現回数の配列である．
この手法は，数値以外の要素を持つ配列に対しても用いることができるので，統計学で言う質的データ（カテゴリデータ）の集計を実現することができる．
例．数値以外の要素を持つ配列の集計

Enter>>> a = np.array([’a’,’b’,’a’,’c’,’b’])Enter>>> (u,c) = np.unique(a,return counts=True)←要素数の集計←戻り値の確認Enter>>> u,c←非数値要素の配列(array([’a’, ’b’, ’c’], dtype=’<U1’), array([2, 2, 1], dtype=int64))←集計できている■ 参考
上の例の unique の戻り値のタプルを辞書オブジェクトにしておくと便利なことがある．
例．unique の集計結果を辞書にする（先の例の続き）>>> d = dict( zip(u,c) ) Enter
d

←内容確認

Enter

{’a’:

←集計結果を zip オブエジェクトにした後で辞書オブジェクトにする

2, ’b’:>>> d[’b’]2, ’c’:

Enter←辞書オブジェクト

1}←要素 ’b’ の個数を求める← ’b’ の個数

2得られた辞書オブジェクトを変数に割り当てておくと，要素の集計表として利用できる．

3.1.10.3

整数要素の集計

負でない整数要素（0 以上の整数の要素）の個数を集計するための関数 bincount がある．
例．整数要素の集計>>> a = np.array([1,2,2,3,3,3,4,4,4,4,5,5,5,5,5]) Enter>>> np.bincount(a) Enter←サンプルデータの配列←集計

array([0, 1, 2, 3, 4, 5], dtype=int64)←集計結果

集計の結果「0 が 0 個，1 が 1 個，2 が 2 個，3 が 3 個，4 が 4 個，5 が 5 個」存在することがわかる．すなわち，結果の配列のインデックスが元の配列の要素に対応する．

3.1.10.4

指定した条件を満たす要素の集計

count nonzero 関数を使用すると，指定した条件を満たす要素の個数を得ることができる．
例．条件を満たす要素の個数を求める>>> q = np.arange( 10 )>>> print( q )Enter[0 1 2 3 4 5 6 7 8 9]

←内容確認
← 0〜9 の配列（要素数は 10）>>> np.count nonzero( q < 4 )4

3.1.11Enter← 4 未満の要素の個数を求める

Enter← 4 以上の要素の個数を求める←個数>>> np.count nonzero( q >= 4 )6←サンプルデータの作成

Enter

←個数
配列に対する演算：1 次元から 1 次元

NumPy に用意されている数学関数は，配列から配列を生成することができる．これを応用すると関数のプロット（2 次元）が実現できる．

75

例．正弦関数の配列の生成>>> import numpy as np←パッケージを’np’ として読み込んでいる

Enter

Enter

>>> lx = np.arange(0.0,6.28,0.01)
Enter>>> ly = np.sin(lx)←データ列（定義域）の生成←上記データ列の各要素に対する正弦関数の値の配列の生成

これで，定義域 lx に対する正弦関数の値域 ly が生成された．これらデータ列を matplotlib パッケージでプロットする例を次に示す．
例．（つづき）正弦関数の配列のプロット>>> import matplotlib.pyplot as plt
Enter>>> plt.plot(lx,ly)← matplotlib パッケージを’plt’ として読み込んでいる

Enter←プロットオブジェクトの生成[<matplotlib.lines.Line2D object at 0x0000026B4AF4B828>]>>> plt.show()

Enter

←生成結果

←プロットを表示

この結果，図 37 に示すようなプロットが表示される．

図 37: プロットの表示
あるいは，plt.bar(lx,ly) とすることで棒グラフを描画することもできる．matplotlib に関しては「3.1.12 データの可視化」で説明する．
ここで紹介した正弦関数 sin は NumPy が提供する関数群の中の 1 つであり，この他にもたくさんの関数が提供されている．統計処理において使用頻度が高いものを表 19 に示す24 ．詳しくは Nympy の公式サイトを参照のこと．
表 19: NumPy が提供する関数の一部

3.1.12

関数

説明

関数

説明

sum

配列要素の合計を求める

mean

配列要素の平均を求める

var

配列要素の分散を求める

std

配列要素の標準偏差を求める

max

配列要素の最大値を求める

min

配列要素の最小値を求める

データの可視化（基本）matplotlib はデータを可視化するためのオープンソースのパッケージであり，関連情報がインターネットサイト
http://matplotlib.org/ で公開されている．matplotlib に含まれるデータの可視化の機能は matplotlib.pyplot モジュー
ルにあり，これを読み込むには次のようにする．

import matplotlib.pyplot as plt
こうすることで，パッケージの別名として plt を指定することができ，可視化のための関数，クラス，プロパティを‘plt.〜’ として記述することができる．
（以後の説明ではこの慣例に従う）

24 使用方法は「3.1.14 統計に関する処理」（p.93）で説明する．

76

3.1.12.1

作図処理の基本的な手順

上のような形でパッケージを読み込んだ後は，次のような手順で作図処理を行う．

1) 作図の準備
Figure オブジェクトを生成して作図処理に必要となる準備を整える．このとき，グラフの描画サイズをキーワード引数 ‘ﬁgsize=(横のサイズ, 縦のサイズ)’ で指定25 することができる．
例．plt.figure( figsize=(6,2) )← ﬁgure 関数（描画サイズを 6×2 とする）

実行結果として Figure オブジェクトが返される．多くの場合においてこの処理は省略できる．

2) 作図に関する処理
描画するグラフのサイズやタイトルの設定，各種グラフの描画，描画したグラフのファイルへの保存といった各種の処理を行う．

3) 表示に関する処理
show 関数を呼び出して，作成した図を実際にウィンドウに表示する．この段階で作図の流れは完了する．
4) 作図環境の終了処理
close() を呼び出して作図処理を終了する．多くの場合においてこの処理は省略できる．
3.1.12.2

2 次元のプロット：折れ線グラフ

正弦関数と余弦関数をプロットするプログラムを例に挙げて，2 次元プロットの基本的な方法について説明する．まずプログラム例 nplot01.py を示す．
プログラム：nplot01.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24

# coding : utf -8# ライブラリの読み込み
import numpy as np
import matplotlib . pyplot as plt# データ列の生成
lx = np . arange (0.0 ,6.28 ,0.01)
ly1 = np . sin ( lx )ly2 = np . cos ( lx )# 定義域の生成# 正弦関数の列# 余弦関数の列# データ列のプロット
plt . figure ( figsize =(6 ,3) )# 作図処理の開始（省略可）
plt . plot ( lx , ly1 , label = ’ sin ( x ) ’)
# プ ロ ッ ト(1)plt . plot ( lx , ly2 , label = ’ cos ( x ) ’)
# プ ロ ッ ト(2)plt . hlines ([ -1 ,0 ,1] ,# 水平の線
0 , np . pi *2 , ls = ’ - - ’ , lw =1.5 , color = ’# b0b0b0 ’)
plt . vlines ([0 , np . pi /2 , np . pi , np . pi *3/2 , np . pi *2] ,-1 ,1 , ls = ’ - - ’ , lw =1.5 , color = ’# b0b0b0 ’)# 垂直の線# 横軸ラベルplt . xlabel ( ’x ’)
plt . ylabel ( ’y ’)# 縦軸ラベルplt . legend ()# 凡例の表示plt . title ( ’ trigonometric functions : sin , cos ’) # タ イ ト ル の 表 示
plt . show ()# プロットの表示
plt . close ()# 作図処理の終了（省略可）

プログラムの説明：

7〜9 行目で定義域の集合 lx とそれに対する，正弦関数，余弦関数の値域の集合 ly1, ly2 を生成している．それらをプロットしているのが 13,14 行目であり，plot 関数を使用している．plot 関数の第 1，第 2 の引数に横軸データと縦軸データをそれぞれ与え，キーワード引数 ’labe=’にそのデータ列のラベルを与える．これはプロットを表示する際の凡例となる．
プログラムの 15〜18 行目では hlines，vlines 関数によって水平と垂直の線を描いている．プログラムの 19,20 行目
はグラフの横軸と縦軸のラベルを関数 xlabel，ylabel で与えている．21 行目では関数 legend によってグラフに凡例を付与している．22 行目では関数 title によってグラフにタイトルを付与している．
（表 21 参照）
最後に関数 show によって実際にプロットを表示している．
25 サイズの単位はインチであるが，表示に使用するデバイス（ディスプレイ）によって若干の違いが生じる．

77

このプログラムを実行すると図 38 のようなプロットが表示される．

図 38: プロットの表示【plot 関数のキーワード引数】

plot 関数のキーワード引数には先に説明した ’label=’

以外にも様々なもの（表 20）がある．

表 20: plot 関数のキーワード引数（一部）
キーワード引数説明

label=凡例「凡例」を文字列で与える．False を与えると凡例を表示しない．

color=色描画色を指定する．次の文字列が指定できる．

’red’, ’green’, ’blue’, ’cyan’, ’magenta’, ’yellow’, ’black’
この他にも ‘#’ で始まる 16 進数表現の RGB 指定の文字列 ∗ や カラーマップを用いた方法もある．

lw=太さ

描画の線の太さを与える．単位はポイント

ls=スタイル線のスタイルを次のような文字列で与える．

’-’（実線：デフォルト），’--’（破線），’:’（点線），’-.’（一点鎖線），’None’（線なし）（他にもあり）
marker=
マーカーの種類

マーカーの種類を次のような文字列で与える．

’.’（ドット），’o’（丸），’s’（■），’*’（星），’+’（十字），’x’（×），’^’（三角形），’v’（逆三角形），’>’（右向き三角形），’<’（左向き三角形）（その他多数）

markersize=
マーカーのサイズ

マーカーのサイズを数値で与える．単位はポイント

alpha=α値

透明度を

0≤α≤1

の範囲で指定する．大きいほど濃い．
* HTML，CSS でよく用いられる色表現．

【水平，垂直の線を描く関数】● hlines([縦位置のリスト]，左端の位置，右端の位置，オプション…)「左端の位置」〜「右端の位置」の水平の線を描く，第 1 引数に与えた「縦位置のリスト」の要素に対応した縦位
置の水平線（複数）を描く．第 1 引数にスカラーを与える（1 つの線の描画）こともできる．
● vlines([横位置のリスト]，下端の位置，上端の位置，オプション…)「下端の位置」〜「上端の位置」の垂直の線を描く，第 1 引数に与えた「横位置のリスト」の要素に対応した横位
置の垂直線（複数）を描く．第 1 引数にスカラーを与える（1 つの線の描画）こともできる．

hlines，vlines 関数の「オプション」には plot 関数のキーワード引数に与えるものと同じものがいくつか使用でき
る．
【グラフ描画に関する各種の設定】
グラフ描画に関する各種の設定を行う関数を表 21 に示す．

78

関数

表 21: グラフ描画に関する各種の設定を行う関数
説明
関数
説明

xlim( 下限, 上限 )横軸の描画範囲の指定

ylim( 下限, 上限 )縦軸の描画範囲の指定

xlabel( 横軸ラベル )横軸のラベルの設定

ylabel( 縦軸ラベル )縦軸のラベルの設定

title( タイトル )グラフのタイトルの設定

legend( )凡例の表示

線のスタイル，色，太さを設定する例として，次のプログラム nplot02.py を示す．これは，不連続な関数（正接関数：tan(x)）を 3 つの定義域
π
3π
π
3π
5π
π
≤x≤
≤x≤
− ≤x≤ ，
，
2
2
2
2
2
2
に分けてプロットする例であり，それぞれの定義域で線の設定を異なるものにしている．
プログラム：nplot02.py
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

# coding : utf -8# モジュールの読み込み
import numpy as np
import matplotlib . pyplot as plt# データ列の生成
p1 = -1.0 * np . pi / 2.0
p2 = np . pi / 2.0
p3 = 3.0 * np . pi / 2.0
p4 = 5.0 * np . pi / 2.0
lx1
ly1
lx2
ly2
lx3
ly3

=
=
=
=
=
=

np . arange ( p1 +0.01 , p2 , 0.01)
np . tan ( lx1 )np . arange ( p2 +0.01 , p3 , 0.01)
np . tan ( lx2 )np . arange ( p3 +0.01 , p4 , 0.01)
np . tan ( lx3 )

#
#
#
#
#
#

定 義 域 の 生 成(1)正 接 関 数 の 列(1)定 義 域 の 生 成(2)正 接 関 数 の 列(2)定 義 域 の 生 成(3)正 接 関 数 の 列(3)# データ列のプロット
plt . plot ( lx1 , ly1 , color = ’ red ’ , lw =3 , ls = ’: ’plt . plot ( lx2 , ly2 , color = ’ black ’ , lw =2 , ls = ’ - - ’
plt . plot ( lx3 , ly3 , color = ’ blue ’ , lw =1 , ls = ’ -. ’plt . grid ( ls = ’ - - ’ , lw =0.8 , alpha =1.0)
plt . ylim ( -100 ,100)
plt . xlabel ( ’x ’)# 横軸ラベルplt . ylabel ( ’y ’)# 縦軸ラベルplt . title ( ’ trigonometric functions : tan ( x ) ’)plt . show ()# プロットの表示) # プ ロ ッ ト(1)) # プ ロ ッ ト(2)) # プ ロ ッ ト(3)# グリッド表示# タイトルの表示

このプログラムを実行すると図 39 のようなプロットが表示される．

図 39: プロットの表示
プロットにグリッド線を描くには grid 関数を実行する．この関数の引数には plot 関数のキーワード引数と共通するものがある．

79

3.1.12.3

グラフの目盛りの設定

特に指定しない場合はグラフの目盛りは自動的に作成される．
例．自動的に付けられる目盛り>>> import numpy as np← NumPy の読込みEnter>>> import matplotlib.pyplot as plt← matplotlib の読込みEnter>>> y = np.sin( x )Enter←横軸データの作成

Enter>>> x = np.linspace( -2*np.pi, 2*np.pi, 100 )←縦軸データの作成←描画処理の開始>>> plt.figure( figsize=(4,2) )Enter<Figure size 400x200 with 0 Axes>>>> plt.plot( x, y )Enter←グラフのプロット[<matplotlib.lines.Line2D object at 0x0000015DC85DADC8>]>>> plt.grid()

Enter←グリッド線の表示>>> plt.show()

Enter←描画の実行

この処理の結果，図 40 の (a) のような目盛りが表示される．

(a) 目盛りの自動設定(b) 独自の目盛りの設定

図 40: プロットの表示
独自の目盛りを設定するには次のような関数 xticks，yticks を使用する．
横軸の設定：

xticks( ticks=[目盛り位置のリスト] )縦軸の設定：

yticks( ticks=[目盛り位置のリスト] )これらを使用する例を次に示す．
例．独自の目盛りを設定（先の例の続き）

Enter>>> fig = plt.figure( figsize=(4,2) )>>> g = plt.plot( x, y )Enter>>> t1 = plt.xticks(ticks=[-2*np.pi, -np.pi, 0, np.pi, 2*np.pi]) Enter ←横軸目盛りの設定>>> t2 = plt.yticks(ticks=[-1,0,1])>>> plt.grid()Enter>>> plt.show()Enter←縦軸目盛りの設定

Enter

この処理の結果，図 40 の (b) のような目盛りが表示される．

xticks，yticks 関数にキーワード引数 ‘visible=False’ を与えると，図 41 の (a) のように目盛りの数値が表示されない．
例．目盛りの数値を非表示にする（先の例の続き）>>> fig =plt.figure( figsize=(4,2) )>>> g = plt.plot( x, y )

Enter

Enter

>>> t1 = plt.xticks(ticks=[-2*np.pi, -np.pi, 0, np.pi, 2*np.pi], visible=False )>>> t2 = plt.yticks(ticks=[-1,0,1], visible=False )>>> plt.grid()Enter>>> plt.show()

Enter

Enter

また，xticks，yticks 関数のキーワード引数 ‘ticks=’ に空リストを与えると，目盛りが非表示となる．

80

Enter

(a) 目盛りの数値を非表示に設定(b) 目盛りなし

図 41: プロットの表示
例．目盛りを非表示にする（先の例の続き）>>> fig = plt.figure( figsize=(4,2) )>>> g = plt.plot( x, y )Enter>>> t1 = plt.xticks( ticks=[] )Enter>>> t2 = plt.yticks( ticks=[] )Enter>>> plt.grid()Enter>>> plt.show()

Enter

Enter

これを実行すると，図 41 の (b) のようなグラフが表示される．

3.1.12.4

複数のグラフの作成

1 枚の図に複数のグラフを作成するには subplots メソッドを使用する．subplots を呼び出す際にグラフの縦横の並び（行，列の数）を指定すると，それに対応する作図用オブジェクトが生成される．実際にプログラムの例を示して説明する．
■ 2 つのグラフを作成する例
正弦関数と余弦関数の 2 つを別のグラフとして作成するプログラム nplot02-2.py を次に示す．
プログラム：nplot02-2.py
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

# coding : utf -8# モジュールの読込み
import numpy as np
import matplotlib . pyplot as plt# データ列の生成
x = np . arange ( -6.3 , 6.3 , 0.01) # 定 義 域 の 生 成
y1 = np . sin ( x )# 値 域 の 生 成(1)y2 = np . cos ( x )# 値 域 の 生 成(2)# matplotlibによるプロット( fig , ax ) = plt . subplots (2 , 1 , figsize =(5 ,3))
plt . subplots_adjust ( hspace =1.0)
ax [0]. plot (x , y1 , linewidth =1 , color = ’ red ’)ax [0]. set_title ( ’ sin ( x ) ’)ax [0]. set_ylabel ( ’y ’)
ax [0]. set_xlabel ( ’x ’)
ax [0]. grid ( True )ax [1]. plot (x , y2 , linewidth =1 , color = ’ green ’)ax [1]. set_title ( ’ cos ( x ) ’)ax [1]. set_ylabel ( ’y ’)ax [1]. set_xlabel ( ’x ’)
ax [1]. grid ( True )plt . show ()このプログラムを実行してグラフを表示した例を図 42 に示す．
プログラムの解説：

nplot02-2.py の 8〜10 行目で定義域と値域（正弦関数，余弦関数）を生成している．13 行目で 2 行 1 列の並びでグ81

図 42: 2 つのグラフを表示した例（縦に 2 つ）
ラフを表示する形で subplots を呼び出している．
書き方：

subplots( 行数, 列数 )また，このときキーワード引数 ﬁgsize=( 横のサイズ, 縦のサイズ ) を与えると，グラフ全体のサイズを指定することができる．subplots の実行後，matplotlib.ﬁgure.Figure オブジェクトと matplotlib.axes.Axes オブジェクトのタプルが返される．今回のプログラムでは，これらを (fig, ax) に受け取っており，ax[インデックス] に対して描画処理を行っている．

14 行目にあるように subplots adjust メソッドを呼び出すと，描画するグラフの間隔を設定することができる．縦に並ぶグラフの上下の間隔はキーワード引数 hspace に，横に並ぶグラフの左右の間隔はキーワード引数 wspace に指定
する．
プログラム nplot02-2.py の 13〜14 行目を，(fig, ax) = plt.subplots(1, 2, figsize=(7,3))
plt.subplots adjust(wspace=0.4)と書き換えると，左右にグラフを並べる形の表示となる．
（図 43 参照）

図 43: 2 つのグラフを表示した例（横に 2 つ）
■ 縦横にグラフを表示する例
正弦関数，余弦関数，指数関数，対数関数の 4 つを別のグラフとして作成するプログラム nplot02-4.py を次に示す．
プログラム：nplot02-4.py
1
2
3
4
5
6
7
8
9

# coding : utf -8# モジュールの読込み
import numpy as np
import matplotlib . pyplot as plt# データ列の生成
x1 = np . arange ( -6.3 , 6.3 , 0.01) # 定 義 域 の 生 成 ( 1 )y1 = np . sin ( x1 )# 値 域 の 生 成(1)

82

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

y2 = np . cos ( x1 )y3 = np . exp ( x1 )# 値 域 の 生 成(2)# 値 域 の 生 成(3)x2 = np . arange (0.01 , 10 , 0.01)
y4 = np . log ( x2 )# 定 義 域 の 生 成(2)# 値 域 の 生 成(4)# matplotlibによるプロット( fig , ax ) = plt . subplots (2 , 2 , figsize =(8 ,4))plt . subplots_adjust ( wspace =0.3 , hspace =0.7)
ax [0 ,0]. plot ( x1 , y1 , linewidth =1 , color = ’ red ’)ax [0 ,0]. set_title ( ’ sin ( x ) ’)ax [0 ,0]. set_ylabel ( ’y ’)
ax [0 ,0]. set_xlabel ( ’x ’)
ax [0 ,0]. grid ( True )ax [1 ,0]. plot ( x1 , y2 , linewidth =1 , color = ’ green ’)ax [1 ,0]. set_title ( ’ cos ( x ) ’)ax [1 ,0]. set_ylabel ( ’y ’)ax [1 ,0]. set_xlabel ( ’x ’)
ax [1 ,0]. grid ( True )ax [0 ,1]. plot ( x1 , y3 , linewidth =1 , color = ’ blue ’)ax [0 ,1]. set_title ( ’ exp ( x ) ’)ax [0 ,1]. set_ylabel ( ’y ’)
ax [0 ,1]. set_xlabel ( ’x ’)
ax [0 ,1]. grid ( True )ax [1 ,1]. plot ( x2 , y4 , linewidth =1 , color = ’ black ’)ax [1 ,1]. set_title ( ’ log ( x ) ’)ax [1 ,1]. set_ylabel ( ’y ’)ax [1 ,1]. set_xlabel ( ’x ’)
ax [1 ,1]. grid ( True )plt . show ()プログラムの解説：

nplot02-4.py の 8〜14 行目でデータ列（定義域，正弦関数，余弦関数，指数関数，対数関数）を生成している．17
行目で 2 行 2 列の並びでグラフを表示する形で subplots を呼び出している．この結果として生成されたオブジェクト

ax[行インデックス, 列インデックス] に対して描画処理を行っている．
このプログラムを実行してグラフを表示した例を図 44 に示す．

図 44: 縦横に 4 つのグラフを表示した例

3.1.12.5

matplotlib のグラフの構造

1 つのグラフを描画する方法と複数のグラフを描画する方法について，別々のケースとして先に解説したが，ここでは matplotlib が描画するグラフの構造について説明し，両方のケースの違いについての理解を促す．その前に，

matplotlib が描くグラフの各部分について改めて説明する．

83次のようなプログラム nplot02-6.py が作成するグラフを例に用いて説明する．
プログラム：nplot02-6.py
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

# coding : utf -8# ライブラリの読み込み
import numpy as np
import matplotlib . pyplot as plt# デ ー タ1
x1 = np . linspace ( -2.2 ,2.2 ,100)
y1 = x1 **5 -5* x1 **3+4* x1# デ ー タ2x2 = np . linspace ( -2 ,2 ,100)
y2 = x2 **2 -1########################################################## 2つ の 図##########################################################( fig , axs ) = plt . subplots (1 ,2 , figsize =(9 ,4))plt . subplots_adjust ( wspace =0.32)# 1つ 目 の 図
axs [0]. set_xlim ( x1 . min () , x1 . max ())
axs [0]. set_ylim ( y1 . min () , y1 . max ())
axs [0]. plot ( x1 , y1 )axs [0]. vlines (0 , y1 . min () , y1 . max () , lw =1.5 , color = ’ gray ’)
axs [0]. hlines (0 , x1 . min () , x1 . max () , lw =1.5 , color = ’ gray ’)
axs [0]. grid ( True )axs [0]. set_title ( ’ x **5 -5* x **3+4* x ’)axs [0]. set_xlabel ( ’x ’)
axs [0]. set_ylabel ( ’y ’)# 2つ 目 の 図
axs [1]. set_xlim ( x2 . min () , x2 . max ())
axs [1]. set_ylim ( y2 . min () , y2 . max ())
axs [1]. plot ( x2 , y2 )axs [1]. vlines (0 , y2 . min () , y2 . max () , lw =1.5 , color = ’ gray ’)
axs [1]. hlines (0 , x2 . min () , x2 . max () , lw =1.5 , color = ’ gray ’)
axs [1]. grid ( True )axs [1]. set_title ( ’ x **2 -1 ’)axs [1]. set_xlabel ( ’x ’)
axs [1]. set_ylabel ( ’y ’)
fig . suptitle ( ’ Multiple plots ’)plt . show ()このプログラムは 2 つの関数 y = x5 − 5x3 + 4x，y = x2 − 1 のグラフを描くものであり，実行すると図 45 のようなグラフが表示される．

図 45: nplot02-6.py の実行結果
このグラフを図解すると図 46 のような部分から成ることがわかる．
【グラフの各部分の説明】● Figure オブジェクト
これは matplotlib が show メソッドで描画するグラフ全体を意味する．このオブジェクトはグラフ全体のタイトルを意味する suptitle を持つ．Figure オブジェクトは AxesSubplot オブジェクトを持ち，これが具体的に描画されるグ84

図 46: matplotlib のグラフの構成ラフである．複数のグラフを同時に描画するケースでは，1 つの Figure オブジェクトが複数の AxesSubplot を配列の形で保持する．
● AxesSubplot オブジェクト
これはプロットされた個々のグラフ平面を意味する．このオブジェクトは下記のような部分を持つ．

xlabel-グラフの横軸ラベル

ylabel-グラフの縦軸ラベル

title

-

グラフのタイトル

グラフのタイトルや軸ラベル，描画範囲を設定するメソッドが，1 つのグラフを描画する場合と複数のグラフを描画する場合で異なる．これは，処理の対象とするオブジェクトが異なることに起因する．すなわち，下記のような 2
つの異なる描画形態がある．

1. Figure オブジェクトが唯 1 つの AxesSubplot オブジェクトのみを持つ場合描画に関する各種のメソッドは最上位の Figure オブジェクトに対して行う．実際の処理は Figure オブジェクト配下の AxesSubplot オブジェクトに対して行われる．

2. Figure オブジェクトが複数の AxesSubplot オブジェクト（配列）を持つ場合描画に関する各種のメソッドは個々の AxesSubplot オブジェクトに対して行う．
以上のことを踏まえると，1 つのみのグラフを描画する場合においても，2 つの方法（Figure に対する描画と Axes-

Subplot に対する描画）を取ることができる．次に示す 2 つのプログラム nplot02-5.py，nplot02-7.py は，同じ処理をそれぞれ異なる方法で描画するものである．

85

プログラム：nplot02-5.py

プログラム：nplot02-7.py

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

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

# coding : utf -8# ライブラリの読み込み
import numpy as np
import matplotlib . pyplot as plt# デ ー タ1
x1 = np . linspace ( -2.2 ,2.2 ,100)
y1 = x1 **5 -5* x1 **3+4* x1################################## 1つ の 図##################################
plt . figure ( figsize =(4 ,4) )# 描画範囲の指定
plt . xlim ( x1 . min () , x1 . max ())
plt . ylim ( y1 . min () , y1 . max ())
plt . plot ( x1 , y1 )plt . vlines (0 , y1 . min () , y1 . max () ,lw =1.5 , color = ’ gray ’)plt . hlines (0 , x1 . min () , x1 . max () ,lw =1.5 , color = ’ gray ’)plt . grid ( True )plt . xlabel ( ’x ’)
plt . ylabel ( ’y ’)
plt . title ( ’ x **5 -5* x **3+4* x ’)plt . suptitle ( ’ Single plot ’)
plt . show ()# coding : utf -8# ライブラリの読み込み
import numpy as np
import matplotlib . pyplot as plt# デ ー タ1
x1 = np . linspace ( -2.2 ,2.2 ,100)
y1 = x1 **5 -5* x1 **3+4* x1################################## 1つ の 図 ： 別 の 方 法##################################
plt . figure ( figsize =(4 ,4) )fig = plt . gcf (); ax = plt . gca ()ax . set_xlim ( x1 . min () , x1 . max ())
ax . set_ylim ( y1 . min () , y1 . max ())
ax . plot ( x1 , y1 )ax . vlines (0 , y1 . min () , y1 . max () ,lw =1.5 , color = ’ gray ’)ax . hlines (0 , x1 . min () , x1 . max () ,lw =1.5 , color = ’ gray ’)ax . grid ( True )ax . set_xlabel ( ’x ’)
ax . set_ylabel ( ’y ’)
ax . set_title ( ’ x **5 -5* x **3+4* x ’)
fig . suptitle ( ’ Single plot ’)
plt . show ()nplot02-7.py の 12 行目では，gcf()，gca() によって作図対象の Figure オブジェクトと AxesSubplot を，ﬁg と ax にそれぞれ取得している．
上記 2 つのプログラムが使用しているメソッドの対比を表 22 に示す．
表 22: 各種の設定のための関数の違い
Figure 用メソッド
AxesSubplot 用メソッド

説明

横軸の描画範囲の指定
縦軸の描画範囲の指定

xlim( 下限, 上限 )ylim( 下限, 上限 )set xlim( 下限, 上限 )set ylim( 下限, 上限 )

横軸の設定
縦軸の設定

xticks( 各種の引数 )yticks( 各種の引数 )set xticks( 各種の引数 )set yticks( 各種の引数 )横軸のラベルの設定
縦軸のラベルの設定

xlabel( 横軸ラベル )ylabel( 縦軸ラベル )set xlabel( 横軸ラベル )set ylabel( 縦軸ラベル )グラフのタイトルの設定

title( タイトル )set title( タイトル )先の 2 つのプログラムを実行すると，どちらも図 47 のようなグラフを描画する．

図 47: nplot02-5.py，nplot02-7.py の実行結果

863.1.12.6

グラフの枠を非表示にする方法

グラフの枠は AxesSubplot オブジェクトの spines プロパティとしてアクセスできる．このプロパティは辞書オブジェクト（OrderedDict）であり，上下左右を意味する ’top’, ’bottom’, ’left’, ’right’ のキーを持つ．例えば

AxesSubplot オブジェクト a の上の枠は，
a.spines[’top’]という記述でアクセスでき，それは Spine オブジェクトである．
グラフの枠線を非表示にするには，当該 Spine オブジェクトの表示属性を False にする．例えば AxesSubplot オブ
ジェクト a の上の枠を非表示にするには，

a.spines[’top’].set visible(False)とする．set visible は Spine オブジェクトの表示属性を設定するメソッドである．
以上のことを応用したサンプルプログラム nplot02-8.py を示す．
プログラム：nplot02-8.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22

# coding : utf -8
import numpy as np
import matplotlib . pyplot as plt# サンプルデータ
x = np . linspace (0 ,2* np . pi ,360)
y = np . sin (3* x )# プロット( fig , axs ) = plt . subplots (1 ,4 , figsize =(8 ,2))for (i , ax ) in enumerate ( axs ):# グ ラ フ を4 枚 描 画
ax . plot (x , y )ax . set_xticks ( ticks =[]);
ax . set_yticks ( ticks =[])
# 枠の消去axs [0]. set_title ( ’ no top ’)axs [0]. spines [ ’ top ’]. set_visible ( False )# 上の枠を消去
axs [1]. set_title ( ’ no bottom ’)axs [1]. spines [ ’ bottom ’]. set_visible ( False ) # 下 の 枠 を 消 去
axs [2]. set_title ( ’ no left ’)axs [2]. spines [ ’ left ’]. set_visible ( False )# 左の枠を消去
axs [3]. set_title ( ’ no right ’)axs [3]. spines [ ’ right ’]. set_visible ( False )# 右の枠を消去
plt . show ()このプログラムでは，10〜12 行目で同じグラフを 4 つ描画し，15 行目，17 行目，19 行目，21 行目で枠の属性を非表示にしている．このプログラムを実行すると図 48 のように表示される．

図 48: 枠の非表示

3.1.12.7

極座標プロット

極座標にグラフをプロットするには，描画対象の AxesSubplot を極座標形式（PolarAxesSubplot オブジェクト）にする．これに関して例を挙げて説明する．

87

プログラム：nplotPol01.py

プログラム：nplotPol02.py

1
2
3
4
5
6
7
8
9
10
11

1
2
3
4
5
6
7
8
9
10
11

# coding : utf -8
import numpy as np
import matplotlib . pyplot as plt# データの作成
x = np . linspace ( 0 , 6* np . pi , 1080 )y = 2* x# プロットplt . figure ( figsize =(5 ,5) )ax = plt . subplot ( projection = ’ polar ’)ax . plot ( x , y )plt . show ()# coding : utf -8
import numpy as np
import matplotlib . pyplot as plt# データの作成
x = np . linspace ( 0 , 2* np . pi , 360 )y = np . sin (10* x )+1# プロットplt . figure ( figsize =(5 ,5) )ax = plt . gca ( projection = ’ polar ’)ax . plot ( x , y )plt . show ()上のプログラム nplotPol01.py，nplotPol02.py では 9 行目で AxesSubplot オブジェクトを取得している．具体的には subplot メソッドや gca メソッドを使用するが，このときにキーワード引数 ‘projection=’polar’’ を指定することで，極座標プロット用の PolarAxesSubplot オブジェクトが得られる．
これらプログラムを実行して得られるグラフを図 49 に示す．

図 49: nplotPol01.py，nplotPol02.py の実行結果

3.1.12.8レーダーチャート（極座標の応用）

極座標プロットを応用することでレーダーチャートを作成することができる．サンプルプログラム nplotPol03.py を次に示す．
プログラム：nplotPol03.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22

# coding : utf -8
import numpy as np
import matplotlib . pyplot as plt# データの作成
lbl = [ ’A ’ , ’B ’ , ’C ’ , ’D ’ , ’E ’ , ’F ’]# ラベル
x = np . linspace ( 0 , 2* np . pi , len ( lbl )+1 )# 各ラベルの角度# レーダーチャートにする値# 最初の要素と同じものを最後に加えることでグラフを閉じる
d1 = [1 , 0.4 , 0.2 , 0.7 , 0.5 , 1 , 1 ]# デ ー タ1
d2 = [0.3 , 0.5 , 1 , 0.2 , 0.8 , 0.5 , 0.3 ]# デ ー タ2
# プロットplt . figure ( figsize =(5 ,5) )ax = plt . gca ( projection = ’ polar ’)ax . plot ( x , d1 , label = ’ d1 ’ )ax . plot ( x , d2 , label = ’ d2 ’ )ax . set_xticks ( ticks =[])
ax . set_thetagrids ( x [: -1]*180/ np . pi , lbl )ax . spines [ ’ polar ’]. set_visible ( False )plt . legend ()plt . show ()88# 外周の枠を消去

このプログラムでは，角度のデータ x に対するレーダーチャートのデータ d1，d2 をプロットするものである．レー
ダーチャートの形に描画するために，x の範囲は 0 °〜360 °（0〜2 π ラジアン）とし，データ d1，d2 の末尾には先頭と同じ要素を加えてグラフの周を閉じる．
レーダーチャートの各データ点にラベル（lbl の要素）を表示するには 19 行目にあるように set thetagrids メソッド
を AxesSubplot オブジェクトに対して実行する．
書き方：

set thetagrids( 角度のデータ配列, 対応するラベルのデータ列)

また，極座標グラフの外周の枠線を非表示にするには AxesSubplot オブジェクトの spines[’polar’] プロパティに対して set visible メソッドで非表示の設定（20 行目）をする．
このプログラムを実行すると図 50 のようなレーダーチャートが表示される．

図 50: レーダーチャート

3.1.12.9

日本語の見出し・ラベルの表示

グラフ中の見出しやラベルに日本語フォントを使用するには matplotlib の FontProperties クラスを利用する．このクラスは matplotlib.font manager パッケージにある．
例．日本語フォントの読み込み（Windows 環境）

from matplotlib.font manager import FontProperties
fp = FontProperties(fname=r’C:￥WINDOWS￥Fonts￥msgothic.ttc’, size=11)
これは Windows の環境で標準的に利用できる「MS ゴシック（標準）」を読み込んで，11 ポイントのサイズのフォントとして FontProperties クラスの fp オブジェクトを生成している例である．先の例のプログラム nplot01.py を変更
してタイトル，軸ラベル，凡例を日本語で表示する形にしたプログラム nplot01j.py を示す．
プログラム：nplot01j.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17

# coding : utf -8# モジュールの読み込み
import numpy as np
import matplotlib . pyplot as plt
from matplotlib . font_manager import FontProperties# グラフで使用する日本語フォント
fp = FontProperties ( fname =r ’ C :\ WINDOWS \ Fonts \ msgothic . ttc ’ , size =11)
# データ列の生成
lx = np . arange ( -3.15 ,3.15 ,0.01) # 定 義 域 の 生 成
ly1 = np . sin ( lx )# 正弦関数の列
ly2 = np . cos ( lx )# 余弦関数の列# データ列のプロット
plt . figure ( figsize =(6 ,3) )plt . plot ( lx , ly1 , label = ’ 正 弦 関 数 ’ )# 作図処理の開始（省略可）# プ ロ ッ ト(1)

89

18
19
20
21
22
23
24
25
26
27

plt . plot ( lx , ly2 , label = ’ 余 弦 関 数 ’ ) # プ ロ ッ ト ( 2 )plt . xlabel ( ’ 定 義 域 ’ , fontproperties = fp )# 横軸ラベルplt . ylabel ( ’ 値 域 ’ , fontproperties = fp )# 縦軸ラベルplt . legend ( prop = fp )# 凡例の表示# タイトルの表示
plt . title ( ’ 正 弦 関 数 ， 余 弦 関 数 の プ ロ ッ ト ’ , fontproperties = fp )plt . grid ( True )# 出力
plt . savefig ( ’ nplot01_out . ps ’)# 画像ファイル出力
plt . show ()# プロットの表示

5 行目で FontProperties クラスを読み込み，8 行目でフォントを読み込んで fp に与えている．19,20 行目にあるよ
うに，軸ラベル設定時にキーワード引数 fontproperties=fp を与えると指定したフォントが有効になる．凡例にフォントを設定する場合は 21 行目にあるように legend メソッドのキーワード引数に prop=fp と指定する．
このプログラム実行して作成したグラフの例を図 51 に示す．

図 51: 見出しとラベルを日本語にした例
参考）matplotlib で手軽に日本語フォントを使用するためのサードパーティ製ライブラリとして
japanize-matplotlib が存在している．

3.1.12.10

グラフを画像ファイルとして保存する方法

先のプログラム nplot01j.py の 25 行目の記述は，saveﬁg メソッドを用いて作成したグラフを画像ファイルとして保存する26 ためのものである．これは show メソッドに先立って記述しなければならない．

saveﬁg メソッドの第 1 引数には，保存先のファイル名を与える．ファイルの形式（フォーマット）は，与えたファ
イル名の拡張子によって識別されるが，次のようなものが拡張子として指定できる．

png, svg, pdf, ps, eps
png のようなビットマップ画像を作成する場合は，キーワード引数 dpi=解像度 を与えることができる．

26 注）日本語の文字を含んだ画像ファイルの出力において，‘RuntimeError: TrueType font is missing table’ というエラーが発生することがある．これは pdf,ps,eps のようなベクトルグラフィック系の出力において発生することが多い．
その場合は svg で出力した後で，別のソフトウェアを介して目的の形式に変換するなどの方法を取るのが良い．

90

3.1.133.1.13.1

乱数の生成
一様乱数の生成random 関数は 0 以上 1 未満の乱数を生成する．
書き方：
1) np.random.rand()乱数を 1 つ生成する．

2)np.random.rand(個数)

指定した個数の乱数を配列として生成する．

3)np.random.rand(n,m)

n 行 m 列の乱数の配列を生成する．

例．一様乱数の生成>>> np.random.rand()Enter

0.9002721968823484>>> np.random.rand(5)←乱数を 1 つ生成

←成績結果

Enter

←乱数を 5 個生成←成績結果

array([ 0.32644595, 0.20630809, 0.98017323, 0.09793674, 0.39467418])>>> np.random.rand(5,3)

Enter← 5 行 3 列の乱数配列を生成

array([[ 0.41218582, 0.36665746, 0.14565054],[ 0.2018859 , 0.88586831, 0.88083754],[ 0.73630688, 0.78485615, 0.98865664],[ 0.58109305, 0.75149191, 0.26337745],[ 0.67083326, 0.91048167, 0.9451317 ]])3.1.13.2

整数の乱数の生成

書き方：

np.random.randint(L, H, 個数)←成績結果

整数 L 以上 H 未満の範囲で乱数を，指定した個数生成する．
例．

>>> np.random.randint(0,10,20)

Enter← 0 以上 10 未満の乱数を 20 個生成

array([2, 1, 7, 4, 0, 1, 4, 3, 9, 2, 7, 6, 0, 8, 1, 4, 8, 9, 1, 7])←成績結果

randint の引数の「個数」の所に (n, m) というタプルを与えると n 行 m 列の配列として乱数を生成する．
3.1.13.3

正規乱数の生成normal 関数は正規乱数（正規分布となる乱数）を生成する．
書き方：

np.random.normal(平均, 標準偏差, 生成個数)

生成個数に (n, m) のタプルを与えると n 行 m 列の配列として生成する．
例．

>>> np.random.normal(0,1,10)

Enter←平均 0, 標準偏差 1 の正規分布データを 10 個生成

array([ 0.01706595, -0.44630863, 0.64802007, -0.86528213, 0.11454459,
1.55471322, 0.24815903, 1.16232311, 0.16387414, -0.52767615])>>> np.random.normal(0,1,(5,3))Enter← 5 行 3 列の正規分布データを生成
array([[ 0.79680422, -1.20956605, 0.58653553],[-0.49538379, -0.70013524, -1.68294362],[-2.03277246, 0.7823404 , -1.4837754 ],[ 1.46255008, 0.4963593 , -0.01242249],[ 0.49222816, -0.03615764, 1.31829024]])
3.1.13.4

乱数の seed について

乱数生成用の関数は実行する度に異なる数値を生成する．
（次の例参照）

91←成績結果

例．5 つの正規乱数を 3 回発生させる>>> for i in range(3):...
...

←繰り返しの開始

Enter

print( np.random.normal(0,1,5) )
Enter

Enter

← 5 つの正規乱数を生成←繰り返しの終了← 5 つの正規乱数（以下同様）[-0.97727788 0.95008842 -0.15135721 -0.10321885 0.4105985 ][0.14404357 1.45427351 0.76103773 0.12167502 0.44386323][ 0.33367433 1.49407907 -0.20515826 0.3130677 -0.85409574]

乱数生成を for 文で繰り返しているが，毎回異なる乱数列が得られていることがわかる．しかし，random.seed 関数によって乱数生成の状態を初期化することが可能であり，生成する乱数に再現性を持たせることができる．
（次の例参照）
例．再現性のある乱数生成>>> for i in range(3):←繰り返しの開始

Enter← seed（種）を 0 として乱数生成状態を初期化

Enter

...

np.random.seed(0)...

print( np.random.normal(0,1,5) )

...

Enter

Enter

← 5 つの正規乱数を生成←繰り返しの終了← 5 つの正規乱数← 5 つの正規乱数（同じ乱数列）← 5 つの正規乱数（同じ乱数列）[1.76405235 0.40015721 0.97873798 2.2408932 1.86755799][1.76405235 0.40015721 0.97873798 2.2408932 1.86755799][1.76405235 0.40015721 0.97873798 2.2408932 1.86755799]

NumPy が提供する乱数生成関数は，特定の統計的特徴に沿った形の乱数を生成するための確定的なアルゴリズムを用いている．すなわち，複数の乱数を生成する際，設定された seed（種）を起点として，決められた並びの乱数列を生成する．関数 random.seed は，引数に与えられた数値を乱数生成過程の初期状態として設定する．また，この関数を呼び出すことなく乱数を生成する場合は，seed は自動的に設定される．
このように乱数生成過程に再現性を持たせることは，統計処理や機械学習のためのプログラム開発において，確定的なテストデータを作成するのに必要となる．
参考までに，他の乱数生成関数についても同様の実行例を示す．
例．rand，randint による確定的な乱数列の生成>>> for i in range(3):←繰り返しの開始

Enter← seed（種）を 0 として乱数生成状態を初期化

Enter

...

np.random.seed(0)...

print( np.random.rand(5) )

...

Enter

← 5 つの一様乱数を生成

Enter←繰り返しの終了[0.5488135 0.71518937 0.60276338 0.54488318 0.4236548 ][0.5488135 0.71518937 0.60276338 0.54488318 0.4236548 ][0.5488135 0.71518937 0.60276338 0.54488318 0.4236548 ]>>> for i in range(3):Enter← seed（種）を 0 として乱数生成状態を初期化

np.random.seed(0)...

print( np.random.randint(0,100,10) )
Enter

Enter

← 0 以上 100 未満の整数乱数を生成←繰り返しの終了[44 47 64 67 67 9 83 21 36 87][44 47 64 67 67 9 83 21 36 87][44 47 64 67 67 9 83 21 36 87]
3.1.13.5← 5 つの一様乱数←（同じ乱数列）←（同じ乱数列）←繰り返しの開始

Enter

...
...

Enter
Enter
Enter

← 0 以上 100 未満の整数乱数← 0 以上 100 未満の整数乱数（同じ乱数列）← 0 以上 100 未満の整数乱数（同じ乱数列）

RandomState オブジェクト（次
個別に初期条件を指定して乱数を生成する RandomState オブジェクトについて，実行例を示しながら説明する．
の例参照）

92

例．RandomState オブジェクトを用いた乱数生成

Enter>>> for i in range(3):←繰り返しの開始...

rs = np.random.RandomState(0)Enter← seed（種）を 0 とする乱数発生器 rs を作成...

print( rs.randint(0,100,10) )Enter← 0 以上 100 未満の整数乱数を生成

...

Enter

←繰り返しの終了[44 47 64 67 67 9 83 21 36 87][44 47 64 67 67 9 83 21 36 87][44 47 64 67 67 9 83 21 36 87]← 0 以上 100 未満の整数乱数← 0 以上 100 未満の整数乱数（同じ乱数列）← 0 以上 100 未満の整数乱数（同じ乱数列）

RandomState オブジェクトは乱数発生器と見ることができ，これに対して乱数生成用のメソッドを実行する．この例
では seed を 0 とする RandomState オブジェクト rs を for による繰り返しの度に生成し，それに対して randint メ
ソッドを実行している．結果として先に示した例と同じ乱数列を得ている．

RandomState オブジェクトを用いることで，異なる初期条件を持つ複数の乱数発生器を実現できる．
3.1.14

統計に関する処理

基本的な統計量を算出する方法を示す．

3.1.14.1

合計

配列の要素の合計を求めるには sum メソッドを用いる．
例．統計量の算出：合計>>> r = np.random.normal(4,2,100000)>>> r.sum()Enter

399973.1259455481
3.1.14.2Enter← μ = 4, σ = 2 の正規乱数を 105 個生成←合計を求める←計算結果

最大値，最小値

配列の要素の最大値，最小値を求めるには max，min メソッドをそれぞれ用いる．
例．統計量の算出：最大値，最小値>>> r.max()Enter

12.936924874373553>>> r.min()Enter-5.673905593171707
3.1.14.3（先の例の続き）←最大値を求める←計算結果←最小値を求める←計算結果

平均，分散，標準偏差配列の要素の平均，分散，標準偏差を求めるには mean，var，std メソッドをそれぞれ用いる．
例．統計量の算出：平均，標本分散，標本標準偏差>>> r.mean()Enter

3.9997312594554812>>> r.var()Enter

4.017122067277002>>> r.std()Enter

2.004275945890935（先の例の続き）←平均値を求める←計算結果←標本分散を求める←計算結果←標本標準偏差を求める←計算結果

var, std メソッドに引数を与えずに，あるいはキーワード引数 ‘ddof=0’ を与えて実行すると，標本分散，標本標準偏差をそれぞれ求める．不偏分散，不偏標準偏差 を求めるにはこれらメソッドにキーワード引数 ‘ddof=1’ を与えて実
行する．

93

例．不偏分散，不偏標準偏差（先の例の続き）←計算結果

4.017162238899392←不偏標準偏差を求める

Enter>>> r.std(ddof=1)←計算結果

2.0042859673458255
3.1.14.4←不偏分散を求める

Enter>>> r.var(ddof=1)

分位点，パーセント点

配列の要素の分位点を求めるには quantile 関数を用いる．
例．分位点（先の例の続き）←四分位数 0 の点の値（最小値）を求める

Enter>>> np.quantile( r, 0 )←計算結果-5.673905593171707>>> np.quantile( r, 0.25 )←四分位数 25%の点の値を求める

Enter

←計算結果

2.6465003734023607←四分位数 50%の点の値（中央値）を求める

Enter>>> np.quantile( r, 0.5 )←計算結果

3.999836531264145>>> np.quantile( r, 0.75 )←四分位数 75%の点の値を求める

Enter

←計算結果

5.368313237300546←四分位数 100%の点の値（最大値）を求める

Enter>>> np.quantile( r, 1 )←計算結果

12.936924874373553

この例のように，quantile 関数の第一引数に対象の配列を，第 2 引数にはデータ数の比率を 0〜1.0 の範囲の値で与える．この関数と同様の機能を持った percentile 関数もあり，第 2 引数には要素数の百分率を 0〜100 の範囲の値で与える．

3.1.14.5

区間と集計（階級と度数調査）

データ列を，指定した区間で集計する方法について，例を挙げて説明する．まず，与えられたデータ列が，指定した区間列のどこに（どの階級に）位置するかを調べるために digitize を用いる．
書き方：

digitize( 集計対象のデータ列, bins=区間のデータ列 )digitize によってデータ列 -2.5，-0.5，0.5，2.5 を区間に区切って集計する例を次に示す．
例．digitize の使用例
←データ配列の作成

Enter>>> a = np.array([-2.5, -0.5, 0.5, 2.5])>>> b = np.linspace( a.min(), a.max(), 4 ) Enter ←最小値〜最大値を 3 等分して 4 つのデータにする>>> c = np.digitize( a, bins=b )>>> print(b)[-2.5←区間集計の実行

Enter←区間の区切りの確認

Enter-0.83333333

0.83333333

2.5←区間の区切り]←集計結果の確認>>> print(c)Enter[1 2 2 4]←集計結果

この例で示した集計処理を図 52 で図解する．
最小値

最大値

-2.5
↓
-3

-0.5
↓
-2

-1

-2.5
(0)

0.5
↓
0

-0.833
(1)

2.5
↓
1

2

0.833
(2)

3
2.5

(3)

← データ

← 区間の区切り(4) ← 区間のインデックス

図 52: digitize による区間集計のイメージ最小値未満の区間のインデックスが 0 となっている

94

表 23: bins=[-2.5,-0.83333333,0.83333333,2.5] で構成される区間
区間のインデックス
範囲
備考

(0)

x < −2.5(1)−2.5 ≤ x < −0.83333333(2)−0.83333333 ≤ x < 0.83333333(3)0.83333333 ≤ x < 2.5(4)

2.5 ≤ x

最小値未満の区間

最大値のみを含む区間

上の例では集計結果が変数 c に [1 2 2 4] として得られているが，これは，元のデータ配列 a の各要素が属する区間（表 23）のインデックスを意味する．また，インデックスが 0 の区間はデータの最小値未満を意味するため，この区間に属するデータの個数は 0 である．
次に示す例は，正規乱数のデータ列の各要素がどの階級に属するかを調べるものである．
例．正規乱数のデータ列を区間毎にラベル付け>>> np.random.seed(0)←乱数の初期化27

Enter

Enter

>>> b = np.linspace( a.min(), a.max(), 40 )>>> c = np.digitize(a,bins=b)

Enter>>> print( a[:5], ’￥n’, c[:5] )← μ = 50, σ = 10 の正規乱数を 105 個生成Enter>>> a = np.random.normal(50,10,100000)←集計用の区間データ列←調査の実行Enter←元のデータと集計結果の要素を先頭から 5 つ表示[67.64052346 54.00157208 59.78737984 72.40893199 68.6755799 ]←元のデータ←集計結果：各要素が属する区間のインデックス[29 23 26 31 29]

この例では，正規乱数列 a の最小値から最大値までの範囲を 40 個のデータとして（39 等分して）配列 b に得ている．
更に digitize によって，a の各要素が b のどの区間に属するかを示すインデックスのデータ列として c を得ている．
区間の考え方であるが，区間データ列 b の隣接する要素 bn−1 , bn の間が 1 つの区間であり，bn−1 以上 bn 未満を意味する．
この例において特に注意すべきこととして，b の最初の要素 b[0] は，データ配列 a の最小値であることが挙げられる．このことにより，digitize の結果として得られた配列 c の要素に含まれる 0 は「b[0] 未満の区間」を意味する．また，b の最終要素はデータ配列 a の最大値である．
得られた c に対して bincount 28 を用いると，a の要素の度数分布を得ることができる．
例．bincount による度数調査（先の例の続き）>>> s = np.bincount( c )>>> s.shape

Enter

Enter

←度数分布を取得←配列の形状を調べる(41,)
結果として配列 s に度数分布が得られる．ここで注意しなければならないこととして，s のデータ個数が 41 となって
おり，区間を意味する配列 b よりも要素の数が 1 つ多いことがある．これは，上で述べた注意点（最小値未満を意味する区間の存在）によるものである．この例で得られた配列 s の最初の要素 s[0] は a の最小値未満の度数を意味しており，当然のことではあるが，0 となっている．
（次の例参照）
例．s の内容（先の例の続き）>>> print( s )Enter← s の内容表示

[ 0
2
1
0
2
5 20 38 78 170 321 496 872 1393
2168 3140 4183 5632 6900 8014 8899 9369 9264 8555 7624 6530 5165 3852
2677 1855 1164 751 407 227 115
61
28
15
5
1
1]
27 実行例の再現性のために行った．
28 「3.1.10.3 整数要素の集計」（p.75）参照のこと．

95← s の内容：
先頭要素が 0になっている．

これを matplotlib を用いて棒グラフとしてプロットする例を次に示す．
例．先の配列 s を棒グラフとしてプロットする

import matplotlib.pyplot as plt
plt.figure(figsize=(6,2))
plt.bar( b,s[1:], width=2.0)
plt.xlabel(’class’); plt.ylabel(’frequency’)plt.show()
この例では，プロットするデータを s[1:] としているが，これは区間データの配列 b に合せるためである．
これを実行すると，図 53 に示すようなグラフが表示される．

図 53: 度数分布のプロット【参考：指定した区間で度数を集計する方法】
先の例で作成したデータ配列 a の最小値と最大値は次の通りである．
例．配列 a の最小値と最大値（先の例の続き）>>> a.min(),a.max()←最小値と最大値の確認

Enter(1.4788234681988328, 92.41771912903697)←最小値と最大値

これらの値から判断し，0〜90 までの 5 刻みの区間で度数を集計することを考える．
例．0〜90 までの区間を 5 刻みで集計（先の例の続き）

Enter>>> b2 = np.linspace( 0, 90, 19 )>>> print( b2 )← 0〜90 までを 18 等分して 19 個のデータ配列を作成

←内容確認

Enter

[ 0. 5. 10. 15. 20. 25. 30. 35. 40. 45.
50. 55. 60. 65. 70. 75. 80. 85. 90.]>>> c2 = np.digitize(a,bins=b2)>>> s2 = np.bincount(c2)

Enter

Enter

←区間のデータ列←区間のインデキシング←度数の集計

集計結果として得られた s2 について調べる．
例．集計結果の確認（先の例の続き）>>> s2.shape
(20,)

Enter

←配列形状の調査←長さ 20 の一次元配列>>> print( s2 )[0
2
1
19214 15095

Enter
24
9142

←内容確認

114
4315

528 1588
1682
478

4362
116

得られた s2 をプロットする処理を次に示す．

969027 15030 19257
23
2]
←集計結果

例．プロット処理（先の例の続き）←描画サイズの設定

Enter>>> plt.figure(figsize=(4.5,2))←戻り値<Figure size 450x200 with 0 Axes>>>> plt.bar( b2,s2[1:], width=4.0)←棒グラフの描画

Enter

←戻り値

<BarContainer object of 19 artists>>>> plt.xlabel(’class’); plt.ylabel(’frequency’)Enter←軸ラベルの設定←戻り値

Text(0.5, 0, ’class’)Text(0, 0.5, ’frequency’)>>> plt.show()

Enter

←描画実行

これによって図 54 のようなグラフが表示される．

図 54: 度数分布のプロット（5 刻みに区間調整後）■ 度数分布図（ヒストグラム）の描画に関しては更に簡便な方法があり，それについては後で説明する．
また，棒グラフの描画に関しても後に述べる．
■ bar 関数による棒グラフでヒストグラムを作図する場合，厳密には横軸は区間を表すものではない．
そのため，グラフ全体が左方向に若干（区間の幅の半分ほど）ずれた形になるので注意すること．

3.1.14.6

最頻値を求める方法

区間の集計処理の結果からデータ集合の最頻値（mode）を求める方法について例を挙げて説明する．まず，サンプ
ルデータとして対数正規分布に従う乱数を作成する．そのための例を次に示す．
（numpy，matplotlib.pyplot は読込み済みである前提）
例．μ = 0, σ = 0.5 の対数正規分布に従う乱数の作成>>> np.random.seed(0)Enter←乱数の初期化29>>> dat = np.random.lognormal( 0, 0.5, 1000000 )Enter← 106 個のデータを生成←作図の開始>>> plt.figure( figsize=(6,2) )Enter<Figure size 600x200 with 0 Axes>>>> g = plt.hist(dat,bins=80)

Enter←階級数 80 でヒストグラムを作成>>> plt.xlim(0,4)(0.0, 4.0)>>> plt.show()Enter←作図の実行

この結果，図 55 のようなヒストグラムが表示される．

図 55: 対数正規分布に従う乱数のヒストグラム

29 実行例の再現性のために行った．

97

上の例の実行の結果，区間の境界値の配列が g[1] に，区間毎の度数集計の結果の配列が g[0] に得られる．
例．集計区間の確認：開始部分と終了部分（先の例の続き）>>> print( ’ 区間の先頭:’,g[1][:3] ); print( ’ 区間の末尾:’,g[1][-3:]区間の先頭:[0.08199071 0.21313196 0.34427321]

区間の末尾:[10.31100821 10.44214946 10.57329071]

)

Enter

例．最も大きなデータの度数を持つ区間のインデックスを調べる（先の例の続き）>>> np.argmax( g[0] )5← argmax 関数で最大の要素のインデックス位置を調べる

Enter←インデックス位置が 5 の区間の度数が最大

この結果，g[1][5] と g[1][6] の中間を最頻値であると結論する．
例．最頻値を求める（先の例の続き）>>> md = (g[1][5] + g[1][6]) / 2>>> print( ’ 最頻値:’, md )
最頻値:

←中間値（最頻値）の算出

Enter

←表示処理

Enter
←結果

0.8032675852230751

この例から最頻値は 0.8032675852230751 となる．最頻値をヒストグラムの中に示す処理を次に示す．
例．ヒストグラム中に最頻値を示す（先の例の続き）←作図の開始>>> plt.figure( figsize=(6,2) )Enter<Figure size 600x200 with 0 Axes>>>> g = plt.hist(dat,bins=80)

Enter←ヒストグラムを作成>>> plt.xlim(0,4)(0.0, 4.0)>>> plt.vlines([md], 0, g[0].max(), lw=3, color=’red’ ) Enter ←最頻値の位置に垂直線を描画<matplotlib.collections.LineCollection object at 0x00000190ECD0BC88>>>> plt.show()Enter←作図の実行

この結果，図 56 のようにヒストグラム中に最頻値が図示される．

図 56: ヒストグラムの最も度数の大きい区間を赤線で図示【digitize，bincount を用いて最頻値を求める方法】
先に示した方法は matplotlib の hist 関数の戻り値から最頻値を求めるものであるが，次に，NumPy の digitize，bincount を用いて最頻値を求める方法を示す．
基本的な方法は，先の digitize，bincount に関する説明のところで示したものの応用である．
例．digitize，bincount による度数集計（先の例の続き）>>> b = np.linspace( dat.min(), dat.max(), 81 )>>> dat2 = np.digitize( dat, bins=b )>>> s = np.bincount( dat2 )

Enter

Enter

Enter

←区間の境界のデータを作成←各データを区間のインデックスでラベル付け←上のデータの集計

この例で得られた区間データ b と集計結果 s を用いてヒストグラムを作成する作業を次に示す．

98

例．bar 関数による棒グラフでヒストグラムを描く（先の例の続き）>>> offset = (b[1] - b[0]) / 2 Enter ← bar 関数をヒストグラムに応用する際の横位置のオフセット>>> plt.figure( figsize=(6,2) )Enter<Figure size 600x200 with 0 Axes>←作図の開始>>> plt.bar( b+offset, s[1:], width=0.12 ) Enter ← bar 関数によるヒストグラムの作成<BarContainer object of 81 artists>>>> plt.xlim(0,4)(0.0, 4.0)>>> plt.show()Enter←作図の実行

今回は，bar 関数によるヒストグラム作成における横軸のずれを補正する方法を取った．すなわち，区間の幅の半分（上記 offset）ほどグラフを右にずらす方法を取った．この結果，図 57 のようなヒストグラムが表示される．

図 57: bar 関数で描画したヒストグラム
データの最頻の区間は集計結果（上記 s ）の最大値の要素のインデックスから判断する．
例．集計結果の最大値のインデックス（先の例の続き）>>> s.argmax()
6

Enter

←最大値のインデックスを求める←インデックスは 6

この結果から判断し，b[5] と b[6] の中間が最頻値であると判断する．
注意）digitize 関数における集計区間のインデックスの考え方は，hist 関数の場合とは異なるので注意すること．
次に最頻値を求める例を示す．
例．最頻値の算出（先の例の続き）>>> md2 = (b[5] + b[6]) / 2

Enter←中間値（最頻値）の算出>>> print( ’ 最頻値:’, md2 )

Enter

←表示処理

最頻値:

0.8032675852230751←結果

この例から最頻値は 0.8032675852230751 となる．最頻値をヒストグラムの中に示す処理を次に示す．
例．ヒストグラム中に最頻値を示す（先の例の続き）>>> plt.figure( figsize=(6,2) )Enter<Figure size 600x200 with 0 Axes>←作図の開始>>> plt.bar( b+offset, s[1:], width=0.12 ) Enter ← bar 関数によるヒストグラムの作成<BarContainer object of 81 artists>>>> plt.xlim(0,4)(0.0, 4.0)>>> plt.vlines([md2], 0, s.max(), lw=3, color=’red’ )Enter←最頻値の位置に垂直線を描画<matplotlib.collections.LineCollection object at 0x00000190E8473C48>>>> plt.show()Enter←作図の実行

この結果，図 58 のようにヒストグラム中に最頻値が図示される．

99

図 58: ヒストグラムの最も度数の大きい区間を赤線で図示

3.1.14.7

相関係数

関数 corrcoef を用いると，2 つのデータ列の相関係数を求めることができる．
書き方：

corrcoef( データ列 1, データ列 2 )この関数は「データ列 1」と「データ列 2」の相関係数を相関行列の形で返す．以下に，サンプルデータを作成して相関係数を求める例を示す．
例．サンプルデータの作成

Enter>>> x = np.arange(0,25,0.25); y = 2*x← y = 2x を満たすデータ列 x, y を作成する．

>>>> xr = x + np.random.normal(0,1,100)

Enter← x を乱数で撹乱したデータ列>>>> yr = y + np.random.normal(0,6,100)

Enter← x を乱数で撹乱したデータ列

これによりノイズを含んだ 2 つのデータ列 xr，yr ができた．これの散布図（p.103 「3.1.15.2 散布図」で解説する）
を表示してデータの概観を確認する（次の例）
例．上で作成したデータ列 xr，yr の散布図（先の例の続き）>>> f = plt.figure()Enter>>> g1 = plt.plot(x,y,color=’red’)>>> g2 = plt.scatter(xr,yr)>>> plt.show()

Enter

Enter

Enter

これを実行すると右のような散布図が表示される．横軸が xr，縦軸が yr である．撹乱する前のデータ x，y を直線で表示している．
次にデータ列 xr，yr の相関係数を算出する例を示す．
例．相関係数を求める（先の例の続き）>>> np.corrcoef(xr,yr)←相関係数（相関行列）の算出

Enter

array([[1.
, 0.90157731],[0.90157731, 1.
]])

←相関行列

ここで作成した xr，yr はかなり強い相関があるサンプルである．次に，互いに相関のないデータ列についても相関係数を求める例を示す．
例．サンプルデータの作成>>> xr2 = np.random.rand(100)Enter← 100 個の一様乱数>>> yr2 = np.random.rand(100)Enter← 100 個の一様乱数

これによって得られる xr2，yr2 は一様乱数であり，互いに相関は無い．そのことを散布図で確認する．
（次の例）
例．上で作成したデータ列 xr2，yr2 の散布図（先の例の続き）>>> f = plt.figure( figsize=(4,4) )>>> g = plt.scatter(xr2,yr2)>>> plt.show()

Enter

Enter

Enter

これを実行すると右のような散布図が表示される．横軸が xr2，縦軸が yr2
である．

100

次にデータ列 xr2，yr2 の相関係数を算出する例を示す．
例．相関係数を求める（先の例の続き）←相関係数（相関行列）の算出

Enter>>> np.corrcoef(xr2,yr2)←相関行列

array([[1.
, 0.15953472],[0.15953472, 1.
]])

xr2，yr2 の間に相関はほぼ見られないことがわかる．
データのシャッフル

3.1.14.8

np.random.permutation，np.random.shuﬄe を使用して配列をシャッフルすることができる．前者は元のデータを変更せずにシャッフルした配列を返し，後者は配列そのものにシャッフル処理を行う．
例．配列データのシャッフル

Enter

>>> a

← 0〜9 の配列を作成

Enter>>> a = np.arange(0,10,1)
←内容確認

←結果表示

array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])>>> np.random.permutation(a)←シャッフル (1)Enter←シャッフル結果

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

>>> a

←元の配列の内容確認←変化なし

array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])>>> np.random.shuffle(a)
Enter

>>> a

←シャッフル (2)Enter←元の配列の内容確認←シャッフルされている

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

permutation，shuﬄe は，先に説明した RandomState オブジェクトに対して実行することもできる．
3.1.153.1.15.1

データの可視化（2）ヒストグラムヒストグラムのプロットには matplotlib の hist 関数を使用する．
書き方：

hist( データ配列, bins=階級の数 )「データ配列」の要素を「階級の数」に分類して度数分布図を作成する．この関数は階級のデータ列とそれに対する度数のデータ列などをタプルにして返す．
例．正規乱数のヒストグラム>>> np.random.seed(0)←乱数の初期化30

Enter>>> a = np.random.normal(50,10,100000)>>> plt.figure( figsize=(5,2) )Enter<Figure size 500x200 with 0 Axes>>>> d = plt.hist(a,bins=20)>>> plt.show()

Enter

Enter

Enter

← μ = 50, σ = 10 の正規乱数を 105 個生成←描画サイズの設定←戻り値←ヒストグラムの作成（階級数は 20）←描画実行

この例の実行の結果，図 59 のようなヒストグラムが表示される．
上の例では hist 関数の戻り値を変数 d に得ている．この内容を確認する．

30 実行例の再現性のために行った．

101

図 59: ヒストグラムの表示
例．hist 関数の戻り値の確認（先の例の続き）>>> print( d[0] )←戻り値の最初の要素の確認

Enter[3.0000e+00 2.0000e+00 2.3000e+01 9.9000e+01 4.0900e+02 1.1490e+03
3.0180e+03 6.4130e+03 1.1081e+04 1.5631e+04 1.8079e+04 1.6767e+04
1.2937e+04 7.9430e+03 4.0020e+03 1.6830e+03 5.5600e+02 1.5800e+02
4.0000e+01 7.0000e+00]>>> print( d[1] )←階級毎の度数の配列←戻り値の 2 番目の要素の確認

Enter[ 1.47882347 6.02576825 10.57271303 15.11965782 19.6666026 24.21354738
28.76049217 33.30743695 37.85438173 42.40132652 46.9482713 51.49521608
56.04216086 60.58910565 65.13605043 69.68299521 74.22994 78.77688478
83.32382956 87.87077435 92.41771913]←階級の境界値の配列

このように，hist 関数の戻り値は度数分布の集計結果を与える．戻り値の 2 番目の要素（上記 d[1]）は階級の境界値の配列であり，隣接する 2 つの値 bn−1 , bn が意味する階級の区間は「bn−1 以上 bn 未満」である．ただし，最終の区間のみ「bn−1 以上 bn 以下」（データの最大値を含む）である．
■ 指定した区間で度数を集計する方法
先に digitize 関数のところ（p.96「参考：指定した区間で度数を集計する方法」）で，階級の区切りを指定する方法
について解説したが，hist 関数でもそれと類似の方法で階級の境界値を指定することができる．
（次の例参照）
例．集計区間を明に指定してヒストグラムを作成する（先の例の続き）>>> b = np.linspace( 0, 95, 20 )Enter

←集計区間の境界値の配列を作成>>> plt.figure( figsize=(5,2) )Enter←描画サイズの設定<Figure size 500x200 with 0 Axes>>>> d2 = plt.hist(a,bins=b)>>> plt.show()

Enter

Enter

←戻り値
←集計区間を指定してヒストグラムを作成←描画実行

この例の実行の結果，図 60 のようなヒストグラムが表示される．

図 60: ヒストグラムの表示（階級指定）
上の例では hist 関数の戻り値を変数 d2 に得ている．この内容を確認する．

102

例．hist 関数の戻り値の確認（先の例の続き）>>> print( d2[0] )Enter←戻り値の最初の要素の確認[2.0000e+00 1.0000e+00 2.4000e+01 1.1400e+02 5.2800e+02 1.5880e+03 ←階級毎の度数の4.3620e+03 9.0270e+03 1.5030e+04 1.9257e+04 1.9214e+04 1.5095e+04
配列
9.1420e+03 4.3150e+03 1.6820e+03 4.7800e+02 1.1600e+02 2.3000e+01
2.0000e+00]>>> print( d2[1] )Enter←戻り値の 2 番目の要素の確認[ 0. 5. 10. 15. 20. 25. 30. 35.
65. 70. 75. 80. 85. 90. 95.]

40.

45.

50.

55.

60.

←階級の境界値の配列注意）NumPy の digitize 関数と matplotlib の hist 関数では，区間の考え方が同じではないので注意すること．

3.1.15.2

散布図

散布図のプロットには scatter 関数を使用する．サンプルプログラムを nplot04.py に示す．
プログラム：nplot04.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16

# coding : utf -8# モジュールの読み込み
import numpy as np
import matplotlib . pyplot as plt# データ列の生成
datx = np . random . normal (50 ,10 ,4000)
daty = np . random . normal (50 ,10 ,4000)# 散布図の表示
plt . scatter ( datx , daty , alpha =0.2)
plt . xlabel ( ’x ’)
plt . ylabel ( ’y ’)
plt . grid ( ls = ’ - - ’ , lw =0.8 , alpha =1.0)
plt . title ( ’ mean :50 , SD :10 , total :4000 ’)
plt . show ()これは 4,000 件の 2 次元のデータ列の散布図を作成する例で，それぞれの軸の平均が 50 （μ = 50），標準偏差が 10（σ = 10）となる場合の例である．
このプログラムを実行すると図 61 のようなプロットが表示される．

図 61: プロットの表示
参考．scatter 関数にキーワード引数 ‘s=サイズ’ を与えると，散布図のマーカーのサイズを指定できる．

3.1.15.3

棒グラフ

縦の棒グラフのプロットには bar 関数を，横の棒グラフのプロットには barh 関数を使用する．ここで説明する「棒グラフ」は先に説明したヒストグラムとは異なり，任意に作成した定義域に対する値域のデータ列をプロットするものである．
サンプルプログラムを nplot04-2.py に示す．

103

プログラム：nplot04-2.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23

# coding : utf -8
import numpy as np
import matplotlib . pyplot as plt# NumPyの読込み# matplotlibの読込み# データ列の生成
datx = np . arange ( -1.0 ,1.2 ,0.2)
daty = - datx **2 + 1# 棒グラフの表示( fig , ax ) = plt . subplots ( 1 ,2 , figsize =(9 ,4) )plt . subplots_adjust ( wspace =0.4)
ax [0]. bar ( datx , daty , width =0.17)
ax [0]. set_xlabel ( ’x ’); ax [0]. set_ylabel ( ’y ’)
ax [0]. set_xlim ( -1 ,1)ax [0]. set_title ( ’ - x ^2+1 ’)# 縦の棒グラフax [1]. barh ( datx , daty , height =0.17)
ax [1]. set_xlabel ( ’y ’); ax [1]. set_ylabel ( ’x ’)
ax [1]. set_ylim ( -1 ,1)
ax [1]. set_title ( ’ - x ^2+1 ’)# 横の棒グラフ

plt . show ()棒の太さは bar 関数のキーワード引数 ‘width=’ に，あるいは barh 関数のキーワード引数 ‘height=’ に指定する．
このプログラムを実行すると図 62 のようなプロットが表示される．

図 62: 棒グラフの表示

barh 関数による描画の場合は，グラフの横軸と縦軸が bar 関数の場合と逆になっている．このため，x 軸のラベ
ル，y 軸のラベルを取り違えないように注意すること．

bar，barh 関数は定義域にラベル（文字列のリストなど）を取ることもできる．これに関する例をサンプルプログ
ラム nplot04-5.py に示す．
プログラム：nplot04-5.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14

# coding : utf -8
import numpy as np
import matplotlib . pyplot as plt# NumPyの読込み# matplotlibの読込み# データ列の生成
daty = [ 13515271 , 8839469 , 7483128 , 2610353 ]lbl = [ ’ Tokyo ’ , ’ Osaka ’ , ’ Aichi ’ , ’ Kyoto ’ ]# 棒グラフの表示( fig , ax ) = plt . subplots ( 1 ,2 , figsize =(8 ,4) )plt . subplots_adjust ( wspace =0.4)
fig . suptitle ( ’ Populations 2015 ’)ax [0]. bar ( lbl , daty )# 縦の棒グラフ

104

15
16
17
18
19
20
21
22

ax [0]. set_xlabel ( ’ prefecture ’)ax [0]. set_ylabel ( ’ population ’)# 横の棒グラフax [1]. barh ( lbl , daty )ax [1]. set_xlabel ( ’ population ’)ax [1]. set_ylabel ( ’ prefecture ’)plt . show ()このプログラムを実行すると図 63 のようなプロットが表示される．

図 63: 定義域にラベルを取る棒グラフ

3.1.15.4

円グラフ

円グラフを作成するには pie 関数を使用する．可視化するデータは 1 次元のデータ列であり，全要素の合計を 1.0とする各要素の割合を円弧で図示する．
書き方：

pie( データ列, 各種キーワード引数… )「各種キーワード引数」として使用頻度の高いものについて解説する．
■ 各円弧に与えるラベル：

labels=[ ラベルのリスト ]円グラフの各円弧に表示するラベル（文字列）をリストにして与える．
■ 開始角度：

startangle=角度の値 （単位は度）

データ列に対応する円弧を描き始める位置（角度）を 360 進法の度数で与える．角度の基準（0 °）は，円グラフの中心から右側水平の半径である．
■ 描画方向：counterclock=[True/False]

描画方向を真理値で与える，True を与えると反時計回り，False を与えると時計回りの方向に円弧を描画する．暗黙値は True（反時計回り）である．
■ 各データの割合の表示：

autopct=書式「書式」に従って各データ（各円弧）の割合の値を表示する．書式は文字列で与える．小数点形式で表示する場合
は ’%表示の長さ. 小数点以下の桁数 f ’と記述する．整数形式で表示する場合は ’%表示の長さ d’と記述する．

数値の表示の末尾にパーセント記号を付ける場合は「%%」を書式の末尾に記述する．
■ 円グラフの中心から離れた円弧を描く：

explode=[ 中心からの距離のリスト ]円グラフの各円弧を描く際の「中心からの距離」をリストにして与える．距離の単位は円グラフの半径であり，例
えば 0.1 という値は半径の 10 分の 1 の距離だけ中心から離れた位置を意味する．
■ 円弧の色：colors=[ 色名のリスト ]各円弧の色名を文字列で与えることができる．また ’#rrggbb’ の形式の色コードで与えても良い．リストの要素に0〜1.0 の数値を与えるとグレースケールとなり，その際の数値は明るさ（0 は黒，1.0 は白）を意味する．

105

■ ラベルのスタイルの指定：

textprops=ラベルのスタイル

各円弧のラベルや割合の数値のスタイルを辞書オブジェクト「ラベルのスタイル」として与える．例えばスタイル
を白色の太字にするには

textprops={’color’:’white’, ’weight’:’bold’}とする．
円グラフを様々な形で描く例を次のサンプルプログラム nplot04-4.py に示す．
プログラム：nplot04-4.py
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

# coding : utf -8
import numpy as np
import matplotlib . pyplot as plt# データの作成
x = np . array ( [1 ,3 ,5 ,7 ,9] )# NumPyの読込み# matplotlibの読込み# 値の配列# - - - 作 図 --( fig , ax ) = plt . subplots ( 2 , 3 , figsize =(12 ,8) )# データのみ（各種引数なし）の作図
ax [0 ,0]. pie ( x )ax [0 ,0]. set_title ( ’( a ) no args ’)# 各種引数を指定して作図
lbl = [ ’1 st ’ , ’2 nd ’ , ’3 rd ’ , ’4 th ’ , ’5 th ’]# ラベルのリスト
ax [0 ,1]. pie ( x , labels = lbl , startangle =90 , counterclock = False ,
autopct = ’%.1 f %% ’ )ax [0 ,1]. set_title ( ’( b ) with args ’)# explodeの例
expd = [ 0 , 0 , 0.1 , 0 , 0 ]ax [0 ,2]. pie ( x , labels = lbl , startangle =90 , counterclock = False ,
autopct = ’%.1 f %% ’ , explode = expd )ax [0 ,2]. set_title ( ’( c ) with explode ’)# 色指定の例
clr = [ ’#00 ff00 ’ , ’#0000 ff ’ , ’#00 ffff ’ , ’# ff00ff ’ , ’# ffff00 ’ ]ax [1 ,0]. pie ( x , labels = lbl , startangle =90 , counterclock = False ,
autopct = ’%.1 f %% ’ , explode = expd , colors = clr )ax [1 ,0]. set_title ( ’( d ) color change ’)# 濃淡の例
clr = [ ’0.4 ’ , ’0.5 ’ , ’0.6 ’ , ’0.7 ’ , ’0.8 ’ ]# 明 る さ （ 暗0 〜1.0 明 ）ax [1 ,1]. pie ( x , labels = lbl , startangle =90 , counterclock = False ,
autopct = ’%.1 f %% ’ , explode = expd , colors = clr )ax [1 ,1]. set_title ( ’( e ) gray scale ’)# ラベルのスタイル指定の例
ax [1 ,2]. pie ( x , labels = lbl , startangle =90 , counterclock = False ,
autopct = ’%.1 f %% ’ , explode = expd ,textprops ={ ’ color ’: ’ white ’ , ’ weight ’: ’ bold ’} )ax [1 ,2]. set_title ( ’( f ) label style ’)plt . show ()このプログラムを実行すると図 64 のような円グラフが作成される．
図 64 の (a) は pie 関数の引数にデータ列のみを与えた描画例である．また (b) は，円弧のラベルと割合の値を表示した例，(c) は中心からはみ出た円弧を描いた例，(d) は円弧の色を指定した例，(e) は円弧をグレースケールにした
例，(f) は円弧のラベルと割合の数値を白色太字にした例である．

106

図 64: 円グラフ

3.1.15.5

箱ひげ図

箱ひげ図の作成には boxplot 関数を使用する．
書き方：

boxplot( [データ配列のリスト], labels=[ラベルのリスト] )サンプルプログラムを nplot04-3.py に示す．
プログラム：nplot04-3.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

# coding : utf -8# モジュールの読込み
import numpy as np
import matplotlib . pyplot as plt# データの作成
d1 = np . random . normal (0 ,1 ,1000)
d2 = np . random . chisquare (4 ,1000)
d3 = np . random . gamma (2 ,2 ,1000)# N [0 ,1]# 自 由 度4 の χ^2 分 布# 形 状 母 数2 ， 尺 度 母 数2 の ガ ン マ 分 布# プロットplt . figure ( figsize =(6 ,3) )plt . boxplot ( [ d1 , d2 , d3 ] , labels =[ ’ N [0 ,1] ’ , ’ X ^2( k =4) ’ , ’ Γ ( k =2 , θ = 2 ) ’ ] )plt . ylim ( -4 ,15)
plt . show ()このプログラムでは配列 d1 に正規分布（μ = 0, σ = 1），配列 d2 に χ2 分布（k = 4），配列 d3 にガンマ分布（k = 2, θ = 2）に沿った乱数列がそれぞれ格納される．このプログラムを実行すると図 65(a) のようなプロットが表示される．

boxplot 関数に引数「vert=False」を与えると横方向の箱ひげ図が描画される．プログラム nplot04-3.py の 13〜14
行目を

plt.boxplot( [d1,d2,d3], labels=[’N[0,1]’,’X^2(k=4)’,’ Γ (k=2, θ=2)’], vert=False )
plt.xlim(-4,15.5)と書き換えて実行すると図 65(b) のようなグラフがプロットされる．

107

(a) デフォルト(b) vert=False でプロット

図 65: 箱ひげ図の表示【解説】箱ひげ図
箱ひげ図はデータの度数の分布を表現するものであり，25 パーセント点（Q1/4 ），50 パーセント点（Q2/4 ：中央値），75 パーセント点（Q3/4 ）を「箱」で表示する．また，箱の長さ Q3/4 − Q1/4 を IQR（interquartile range）として，有効なデータの範囲を Q1/4 − IQR 〜 Q3/4 + IQR であると考え，その範囲内にないデータは「外れ値」とみなす．
（図 66）
←

IQR

→

外れ値←

最小値

→外れ値

Q1/4 -1.5×IQR

Q2/4

Q1/4

Q3/4

Q3/4 +1.5×IQR

最大値

図 66: 箱ひげ図

3.1.16

多次元配列に対する演算f

ここではプログラム例を示しながら，高次元の関数の計算方法について説明する．高次元の関数 Rn −→ R の例として次のような関数について考える．

z = cos(

x2 + y 2 )この関数の概形を図 67 に示す．

図 67: z = cos(

x2 + y 2 ) の概形

n 個の独立変数から 1 つの従属変数への関数を求めるには meshgrid 関数を用いて n 次元の定義域の格子を生成し，それに対する関数の値（値域）を算出する方法がある．定義域の格子を生成するには，それを構成する各軸の 1 次元
配列を meshgrid の引数に与える．

108

例．x ∈ (−4.5, 4.5]，y ∈ (−4.5, 4.5] の定義域の格子を生成する>>> x = np.arange(-4.5, 4.5, 0.1)

Enter

← x 軸のデータ列を生成>>> y = np.arange(-4.5, 4.5, 0.1)

Enter

← y 軸のデータ列を生成>>> (X,Y) = np.meshgrid(x,y)← x 定義域の格子を生成

Enter>>> Z = np.cos(np.sqrt(X**2+Y**2))←関数の値域の生成Enter

これにより，X,Y,Z に関数の定義域と値域のデータ配列ができる．これら X, Y, Z は ndarray である．
（次の例参照）
例．meshgrid によって生成された定義域の配列と値域の配列←配列 X の形状の調査

Enter>>> X.shape← 2 次元（90 × 90）の配列であることがわかる(90, 90)←配列 Y の形状の調査

Enter>>> Y.shape← 2 次元（90 × 90）の配列であることがわかる(90, 90)←配列 Z の形状の調査

Enter>>> Z.shape← 2 次元（90 × 90）の配列であることがわかる(90, 90)

meshgrid 関数の働き

3.1.16.1

meshgrid 関数が格子状の配列を作成する様子について解説する．例として 2 次元の格子状の配列を作成するケースについて考える．

2 次元の平面の 2 つの軸を 1 次元の配列で表し，それらから 2 次元の格子を作成する例を示す．
例．meshgrid で作成される配列>>> x = np.array([1,2,3,4])Enter← x 軸の 1 次元配列>>> y = np.array([5,6,7,8])Enter← y 軸の 1 次元配列>>> (X,Y) = np.meshgrid(x,y)

Enter←格子を生成>>> print(X)[[1 2 3 4]
[1 2 3 4][1 2 3 4][1 2 3 4]]>>> print(Y)← 1 つ目の戻り値（配列）の確認

Enter←配列の内容← 2 つ目の戻り値（配列）の確認

Enter[[5 5 5 5]
[6 6 6 6][7 7 7 7][8 8 8 8]]←配列の内容この例で作成された配列 X，Y を図 68 に図解する．

82 つの軸で構成される
2 次元平面

7(1,8)(2,8)(3,8)(4,8)

1

2

3

4

8

8

8

8

(1,7)(2,7)(3,7)(4,7)

1

2

3

4

7

7

7

7

(1,6)(2,6)(3,6)(4,6)

1

2

3

4

6

6

6

6

1

2

3

4

5

5

5

5

y軸

6
5

1

2

3

x軸

4

(1,5)(2,5)(3,5)(4,5)

各格子における x 軸の値( 生成される配列 1)

各格子の座標

各格子における y 軸の値( 生成される配列 2)

図 68: meshgrid が作成する配列

meshgrid が返す 2 つの配列は先の例における配列 X，Y に対応する．配列のインデックスの順序の関係上，配列 Yの上下の表示順序は図 68 の右端のものと比べると逆になっている．

109

3.1.17

データの可視化：3 次元プロット

matplotlib で 3 次元のプロットを実現するには Axes3D クラスを使用する．このクラスを使用するには，次のようにして必要なモジュールを読み込む．

from mpl toolkits.mplot3d import Axes3D
Axes3D オブジェクトを生成するには，コンストラクタの引数に ﬁgure オブジェクトを与える．
例．ax = Axes3D(plt.ﬁgure())
以後，この ax オブジェクトに対して 3 次元描画のメソッドを実行する．
ワイヤフレーム
先に挙げた関数 z = cos( x2 + y 2 ) のワイヤフレームプロットを描画するプログラムを nplot05.py に示す．

3.1.17.1

プログラム：nplot05.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21

# coding : utf -8# モジュールの読み込み
import numpy as np
import matplotlib . pyplot as plt
from mpl_toolkits . mplot3d import Axes3D# meshgridの作成
x = np . arange ( -4.5 , 4.5 , 0.1)
y = np . arange ( -4.5 , 4.5 , 0.1)
(X , Y ) = np . meshgrid (x , y )# 関数の算出
Z = np . cos ( np . sqrt ( X **2+ Y **2))# 関数のプロット
ax = Axes3D ( plt . figure ())
ax . plot_wireframe (X ,Y ,Z , lw =0.5 , color = ’ black ’)ax . set_xlabel ( ’x ’)
ax . set_ylabel ( ’y ’)
ax . set_zlabel ( ’z ’)
plt . show ()17 行目にある plot wireframe メソッドでワイヤフレームを生成している．このメソッドの第 1〜第 3 引数に x, y, z
それぞれの軸のデータを格納する配列を与える．キーワード引数には表 20 に挙げるようなものが指定できる．
軸のラベルを表示するには，18〜20 行目にあるように set xlabel，set ylabel，set zlabel メソッドを使用する．
このプログラムを実行すると図 69 のようなプロットが表示される．

図 69: プロットの表示

3.1.17.2

面プロット（surface plot）

先のワイヤフレーム描画で使用した plot wireframe メソッドの代わりに plot surface メソッドを使用すると面プロット（surface plot）ができる．この際，matplotlib のカラーマップモジュールを使用することで面にカラーマップを施

110すことができる．このためには必要なモジュールを次のようにして読み込んでおく．

from matplotlib import cm
サンプルプログラム nplot05-2.py の実行を例にして面プロットの実行結果を見る．
プログラム：nplot05-2.py
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

# coding : utf -8# モジュールの読み込み
import numpy as np
import matplotlib . pyplot as plt
from mpl_toolkits . mplot3d import Axes3D
from matplotlib import cm# meshgridの作成
x = np . arange ( -4.5 , 4.5 , 0.1)
y = np . arange ( -4.5 , 4.5 , 0.1)
(X , Y ) = np . meshgrid (x , y )# 関数の算出
Z = np . cos ( np . sqrt ( X **2+ Y **2))# 関数のプロット
ax = Axes3D ( plt . figure ())# ax . plot_surface (X , Y , Z , cmap = cm . gray , shade = True )# ax . plot_surface (X , Y , Z , cmap = cm . hot , shade = True )# ax . plot_surface (X , Y , Z , cmap = cm . cool , shade = True )# ax . plot_surface (X , Y , Z , cmap = cm . bwr , shade = True )ax . plot_surface (X , Y , Z , cmap = cm . seismic , shade = True )ax . set_xlabel ( ’x ’)
ax . set_ylabel ( ’y ’)
ax . set_zlabel ( ’z ’)
plt . show ()プログラムの 19〜23 行目が面プロットを実行する部分であり，コメントを切り替えてこの内の 1 つを実行すること
でカラーマップの様子を見ることができる．カラーマップは plot surface のキーワード引数 cmap= に与える．
このプログラムを実行して表示されるグラフのバリエーションを図 70 に示す．

gray

hot

bwr

cool

seismic

図 70: いくつかのカラーマップの例
単純で便利なカラーマップを表 24 に示す．
これらカラーマップを使用した例を「3.1.26.4 サンプルプログラム：画像の三色分解」（p.142）で示す．

111

cmap

表 24: 単純で便利なカラーマップ
説明
cmap
説明

’Reds’

赤の濃淡’Reds r’

赤の濃淡（逆順）’Greens’

緑の濃淡’Greens r’

緑の濃淡（逆順）’Blues’青の濃淡’Blues r’

青の濃淡（逆順）’Greys’

黒の濃淡’Greys r’

黒の濃淡（逆順）* ’Grays’ ではなく’Greys’ であることに注意

3.1.17.3

3 次元の棒グラフ

3 次元の棒グラフを作成するには bar3d を使用する．先に説明したワイヤフレームや面プロットの作成とは方法が異なり，描画対象は Axes3DSubplot オブジェクトで，これは Figure オブジェクトに対して add subplot( projection=’3d’) メソッドを実行して作成する．得られた Axes3DSubplot オブジェクトに対して bar3d メソッドを実行することで3 次元の棒グラフを描画する．

次に，z = cos( x2 + y 2 ) + 1 の棒グラフをプロットするサンプルプログラム nplot05-3.py を示す．
プログラム：nplot05-3.py
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

# coding : utf -8# モジュールの読み込み
import numpy as np
import matplotlib . pyplot as plt
from mpl_toolkits . mplot3d import Axes3D# meshgridの作成
x = np . arange ( -4.5 , 4.5 , 0.5)
y = np . arange ( -4.5 , 4.5 , 0.5)
( X0 , Y0 ) = np . meshgrid (x , y )X = np . ravel ( X0 );Y = np . ravel ( Y0 )# プロット点の作成# 1次 元 に 展 開# 関数の算出
Z = np . cos ( np . sqrt ( X **2+ Y **2)) + 1# 関数のプロット
fig = plt . figure ( figsize =(10 ,5) )ax = fig . add_subplot ( projection = ’3d ’ ) # 3 次 元 プ ロ ッ ト 用 オ ブ ジ ェ ク ト
Btm = np . zeros_like ( Z )# 棒グラフの底ax . bar3d (X , Y , Btm , 0.15 , 0.15 , Z , color = ’ gray ’ , shade = True )ax . set_xlabel ( ’x ’)
ax . set_ylabel ( ’y ’)
ax . set_zlabel ( ’z ’)
plt . show ()8〜10 行目では，関数の定義域の格子（X0,Y0）を作成している．これを 11 行目で 1 次元のデータ列（X,Y）に展開し，それに対する関数の値のデータ列 Z を生成（14 行目）している．

bar3d の引数は次のように与える．
書き方： bar3d( x の配列, y の配列, 棒の底の値の配列, 棒の幅, 棒の奥行, z の配列,

color=色, shade=[True/False] )このメソッドには「棒の底」を与える必要があり，上の例では 20 行目で底を 0 とする配列 Btm を作成している．
このプログラムを実行して描画したグラフを図 71 に示す．

3.1.17.4

3 次元の散布図

3 次元の座標に対しても plot を使用することができる．これを応用すると 3 次元の散布図を作成することができる．
それを行うサンプルプログラムを scatter3d01.py に示す．
プログラム：scatter3d01.py
1
2# coding : utf -8# ライブラリの読込み

112

図 71: z = cos(
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23



x2 + y 2 ) + 1 の棒グラフ

import numpy as np
import matplotlib . pyplot as plt
from mpl_toolkits . mplot3d import Axes3D# データの作成
x1 = np . random . normal (0 ,0.2 ,100)
y1 = np . random . normal (0 ,0.2 ,100)
z1 = np . random . normal (0 ,0.2 ,100)#x2 = np . random . normal (1 ,0.2 ,100)
y2 = np . random . normal (1 ,0.2 ,100)z2 = np . random . normal (0 ,0.2 ,100)# 3次 元 散 布 図
ax = Axes3D ( plt . figure () )ax . plot ( x1 , y1 , z1 , ls = ’ None ’ , marker = ’o ’)
ax . plot ( x2 , y2 , z2 , ls = ’ None ’ , marker = ’o ’)
ax . set_xlabel ( ’x ’)
ax . set_ylabel ( ’y ’)
ax . set_zlabel ( ’z ’)
plt . show ()このプログラムは乱数で構成される 2 つのグループの点の集合を散布するもので，グラフの線の表示を抑止してマーカーのみでプロットしている．このプログラムを実行すると図 72 のようなグラフが表示される．

図 72: 3 次元の散布図の例

113

3.1.18
3.1.18.1

データの可視化：その他
ヒートマップ2 次元の配列（ndarray，リスト）や meshgrid を用いて作成した 3 次元データをヒートマップとして表示するにはpcolor 関数を使用する．この関数にキーワード引数 cmap= を与えることで，ヒートマップの表現に適用するカラー
マップ（先の面プロットと同様）を指定する．
次に示すサンプルプログラム heatmap01.py は 2 次元のリストから，heatmap02.py は 3 次元データからヒートマッ
プを描画するものである．
プログラム：heatmap01.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17

# coding : utf -8# モジュールの読込み
import numpy as np
import matplotlib . pyplot as plt
w = 0.5# 幅
ax = np . arange ( -3 ,3+ w , w )# 横軸の値
ay = np . arange ( -3 ,3+ w , w )# 縦軸の値# 2次 元 デ ー タ の 作 成
a = []for y in ay :a . append ( 1 / ( np . sqrt ( ax **2+ y **2)+1) )# ヒートマップの描画
plt . figure ( figsize =(5 ,5) )plt . pcolor ( a , cmap = plt . cm . hot )plt . show ()このプログラムを実行して作成したヒートマップが図 73 の (a) である．
プログラム：heatmap02.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16

# coding : utf -8# モジュールの読込み
import numpy as np
import matplotlib . pyplot as plt
w = 0.5# 幅
ax = np . arange ( -3 ,3+ w , w )# 横軸の値
ay = np . arange ( -3 ,3+ w , w )# 縦軸の値# 3次 元 デ ー タ の 作 成(X , Y ) = np . meshgrid ( ax , ay )Z = 1 / ( np . sqrt ( X **2+ Y **2)+1)# ヒートマップの描画
plt . figure ( figsize =(5 ,5) )plt . pcolor ( X ,Y ,Z , cmap = plt . cm . hot )plt . show ()このプログラムを実行して作成したヒートマップが図 73 の (b) である．

meshgrid を用いて 3 次元データを作成する場合は，座標の区間が描画されるので，2 次元配列のヒートマップと比較して表示の体裁に若干の差異が生じる．
ヒートマップを作図する matshow も存在する．先のプログラム heatmap01.py と同様の処理を行うプログラム

heatmap03.py を示す．
プログラム：heatmap03.py
1
2
3
4
5
6

# coding : utf -8# モジュールの読込み
import numpy as np
import matplotlib . pyplot as plt
w = 0.5# 幅

114

(a) 2 次元のリストのヒートマップ-1(b) 3 次元データのヒートマップ(c) 2 次元のリストのヒートマップ-2

図 73: ヒートマップの表示
7
8
9
10
11
12
13
14
15
16
17

ax = np . arange ( -3 ,3+ w , w )# 横軸の値
ay = np . arange ( -3 ,3+ w , w )# 縦軸の値# 2次 元 デ ー タ の 作 成
a = []for y in ay :a . append ( 1 / ( np . sqrt ( ax **2+ y **2)+1) )# ヒートマップの描画( fig , ax ) = plt . subplots ( figsize =(5 ,5) )ax . matshow ( a , cmap = plt . cm . hot )plt . show ()このプログラムを実行して作成したヒートマップが図 73 の (c) である．matshow における作図の大きさは subplotsの引数に指定（15 行目）し，matshow は subplots が返す要素の第 2 要素（プログラム中の ax）に対して実行する．

matshow による作図では，pcolor による作図と上下が逆（行の順番が逆）になっている．このことは次のプログラム heatmap04.py で確認できる．
プログラム：heatmap04.py
1
2
3
4
5
6
7
8
9
10
11

# coding : utf -8# モジュールの読込み
import numpy as np
import matplotlib . pyplot as plt# データの作成
a = np . arange (0 ,25 ,1). reshape ( (5 ,5) )# ヒートマップの描画( fig , ax ) = plt . subplots (1 ,2 , figsize =(7 ,3))ax [0]. pcolor ( a , cmap = plt . cm . hot )ax [1]. matshow ( a , cmap = plt . cm . hot )plt . show ()このプログラムを実行すると図 74 のようなヒートマップが表示される．

(a) pcolor によるヒートマップ(b) matshow によるヒートマップ

図 74: 上下の異なるヒートマップ

115【カラーバーの表示】

pcolor，matshow で作成したヒートマップにはカラーバーを添えることができる．基本的な手順は，
1) 作図結果（pcolor，matshow）の戻り値を取得する
2) 上の値を colorbar メソッドに与えてカラーバーを作成するである．colorbar は Figure オブジェクトに対するメソッドである．カラーバーを表示するサンプルプログラム

heatmap05.py を次に示す．
プログラム：heatmap05.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

# coding : utf -8# モジュールの読込み
import numpy as np
import matplotlib . pyplot as plt# データの作成
a = np . arange (0 ,25 ,1). reshape ( (5 ,5) )# ヒートマップの描画( fig , ax ) = plt . subplots (1 ,2 , figsize =(7 ,3))a0 = ax [0]. pcolor ( a , cmap = plt . cm . hot )# 作図結果の戻り値を取得
print ( ’ type of pcolor : ’, type ( a0 ) )a1 = ax [1]. matshow ( a , cmap = plt . cm . cool )# 作図結果の戻り値を取得
print ( ’ type of matshow : ’ , type ( a1 ) )fig . colorbar ( a0 , ax = ax [0] )# pcolor に カ ラ ー バ ー を 添 え る
fig . colorbar ( a1 , ax = ax [1] )# matshow に カ ラ ー バ ー を 添 え る
plt . show ()プログラムの 9，11 行目でヒートマップを作成し，その戻り値を a0，a1 に取得している．それらの値を colorbar
メソッドの第 1 引数に与えて（13，14 行目）カラーバーを作成している．
書き方：

colorbar( 描画結果の戻り値, ax=カラーバーを添える描画面 )「カラーバーを添える描画面」は対象の AxesSubplot オブジェクトである．

heatmap05.py を実行すると図 75 のようにカラーバー付きのヒートマップが表示される．

(a) pcolor によるヒートマップ(b) matshow によるヒートマップ

図 75: カラーバーの表示

3.1.18.2

表の作成

table 関数を使用すると，2 次元の配列を表の形で描くことができる．
書き方：

table( cellText=配列, bbox=[x1 , y1 , x2 , y2 ] )キーワード引数 ‘cellText=’ に表として描画する配列を，‘bbox=’ にグラフ上の表を描く位置を指定する．
整数の乱数を 3 × 3 の配列として生成し，表として描くプログラムの例を pltable01.py に示す．
プログラム：pltable01.py
1
2
3
4
5
6
7

# coding : utf -8# ライブラリの読込み
import numpy as np
import matplotlib . pyplot as plt# - - - テ ー ブ ル （ 2 次 元 配 列 ） の 作 成 --rtbl = np . random . randint (0 ,100 ,(3 ,3))

116

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

print ( rtbl )# 表示処理（文字：標準出力）# - - - 表 の 作 成 ( 1 ) ： 最 も 素 朴 な 表 示 --plt . figure ( figsize =(3 ,2))plt . table ( cellText = rtbl , bbox =[0 ,0 ,1 ,1] )plt . gca (). axis ( ’ off ’)# 軸の目盛りを非表示
plt . title ( ’ Simple table ’)plt . show ()# - - - 表 の 作 成 ( 2 ) ： 見 出 し ， 色 ， 水 平 位 置 の 指 定 --# 色の定義
Ccell = [[ ’# dddddd ’ , ’# ffffff ’ , ’# ffffff ’] ,# セルの色[ ’# ffffff ’ , ’# dddddd ’ , ’# ffffff ’] ,[ ’# ffffff ’ , ’# ffffff ’ , ’# dddddd ’]]Ccol = [ ’# ffbbbb ’ , ’# bbffbb ’ , ’# bbbbff ’]# 列見出しの色
Crow = [ ’# bbffff ’ , ’# ffbbff ’ , ’# ffffbb ’]# 行見出しの色# プロットplt . figure ( figsize =(3 ,2))plt . table (cellText = rtbl ,bbox =[0 ,0 ,1 ,1] ,cellLoc = ’ center ’ ,colLabels =[ ’A ’ , ’B ’ , ’C ’] ,rowLabels =[ ’X ’ , ’Y ’ , ’Z ’] ,cellColours = Ccell ,colColours = Ccol ,rowColours = Crow)
plt . gca (). axis ( ’ off ’)# 軸の目盛りを非表示
plt . title ( ’ row / col label , colours , location ’)plt . show ()プログラムの 7 行目で乱数配列を生成し，内容確認のため 8 行目でそれをターミナルウィンドウに表示する．11〜15
行目でそれを表として描画する．表の描画は 12 行目で行い，グラフ上の表示位置の範囲は (0,0)〜(1,1) としている．
この際，13 行目の記述により縦横の軸の目盛りの表示を抑止している．

19 行目以降では，カラムや行の見出しを付け，セルの色を設定するなどして表を描く処理を記述している．
■ セル内の表示位置の設定

table 関数のキーワード引数 ‘cellLoc=’ に，セル内のデータの表示位置を与える（上記プログラム 29 行目）ことができる．設定する値は ’left’（左寄せ），’center’ （中央揃え），’right’（右寄せ）から選ぶ．
■ カラム，行の見出しの設定

table 関数のキーワード引数 ‘colLabels=’，‘rowLabels=’ にそれぞれカラムの見出しと行の見出しを配列の形で与えることができる．
（上記プログラム 30〜31 行目）■ セルの背景色の設定

table 関数のキーワード引数 ‘cellColours=’，‘colColours=’，‘rowColours=’ にデータのセル，カラム見出し，行見
出しそれぞれの背景色を与えることができる．背景色は対応するセルの色（上記プログラムでは 16 進数の色指定をしている）を配列の形で用意（上記プログラム 19〜23 行目）する．
上記プログラムを実行すると，標準出力（ターミナルウィンドウ）に[[16 77 51][32 39 46][50 61 41]]と表示されれ，図 76 の (a)，(b) の表が順番に表示される．

117

(a) 素朴な形の表(b) 行, カラムの見出しと着色

図 76: 表の描画

3.1.19高速フーリエ変換（FFT）

フーリエ変換は，時間 t の関数 h(t) を別の変数 ω の関数 H(ω) に変換する次のような操作である．
 ∞H(ω) =
h(t) exp(−iωt) dt−∞

また ω = 2π f と解釈すると，時間の関数から周波数の関数への変換であると見ることができ，この変換を応用すると，時間軸で解釈される振動（波形）を周波数成分に展開することができる．
関数 H(ω) は次のようなフーリエ逆変換で元の関数 h(t) に戻る．
 ∞1h(t) =
H(ω) exp(iωt) dω
2π −∞これらフーリエ変換と逆変換は信号解析をはじめとする工学的応用に不可欠な処理である．ここでは NumPy が提供するフーリエ変換と逆変換の機能の使用方法について導入的に解説する．

3.1.19.1

時間領域から周波数領域への変換：フーリエ変換

NumPy の ﬀt パッケージに含まれる ﬀt 関数を使用することで時間の関数を周波数の関数に変換することができる．
書き方：

np.ﬀt.ﬀt(データ列)

これにより，与えたデータ列（時間領域）をフーリエ変換して周波数領域に変換したデータ列を返す．フーリエ変換が対象とするデータは複素数であり，変換によって得られる周波数領域のデータ列も複素数である．通常の信号解析では，扱う波形データは実数で構成されることが一般的であるが，フーリエ変換の結果得られるデータは複素数である．
フーリエ変換により得られたデータ列の横軸のスケール（周波数）を求めるには ﬀtfreq 関数を用いる．
書き方：

np.ﬀt.ﬀtfreq(データ個数, d=時間領域の最大値)

データ個数は ﬀt 関数に与えたデータ列の長さであり，そのデータの最終要素の時刻を時間領域の最大値として与え
る．ﬀtfreq 関数は周波数スケールのデータ列を返す．この値を横軸として，ﬀt 関数で得られた周波数成分のデータ列を縦軸としてプロットすると，周波数領域のプロットができる．ただし，フーリエ変換の結果として得られるデータは複素数である31 ことに注意すること．

3.1.19.2周波数領域から時間領域への変換：フーリエ変逆換

周波数領域のデータ列を時間領域のデータ列に変換（フーリエ変逆換）するには iﬀt 関数を使用する．
書き方：

np.ﬀt.iﬀt(周波数領域のデータ列)

フーリエ変換，フーリエ逆変換の処理を行うサンプルプログラムを npﬀt01.py に示す．
プログラム：npﬀt01.py
12
34# coding : utf -8# ライブラリの読み込み
import numpy as np
import matplotlib . pyplot as plt

31 NumPy での複素数の扱いについては後の「3.1.20 複素数の計算」（p.122）を参照のこと．

118

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

import pylab##########################################################
波形データの生成########################################################### - - - - - 時 間 軸 デ ー タ ----d_x = np . array ( [ i /400.0 for i in range (400)] )# - - - - - 正 弦 波 ----d_sin = np . sin ( 4.0 * np . pi * d_x )# 波形のプロット
pylab . figure ( figsize =(8 ,2))plt . plot ( d_x , d_sin , lw =1.5 , color = ’ black ’)
plt . xlabel ( ’ time ’) # 横 軸 ラ ベ ル
plt . ylabel ( ’y ’)# 縦軸ラベルplt . title ( ’ sin ’)plt . show ()#----- 鋸 歯 状 波 （ ノ コ ギ リ 波 ） - - - - d_saw = np . array ( [ i /100.0 -1.0 for i in range (200)]*2 )# 波形のプロット
pylab . figure ( figsize =(8 ,2))plt . plot ( d_x , d_saw , lw =1.5 , color = ’ black ’)
plt . xlabel ( ’ time ’) # 横 軸 ラ ベ ル
plt . ylabel ( ’y ’)# 縦軸ラベルplt . title ( ’ Saw ’)plt . show ()# - - - - - 三 角 波 ----tmp = [ i /50.0 -1.0 for i in range (100)]d_tri = np . array ( ( tmp + tmp [:: -1])*2 )# 波形のプロット
pylab . figure ( figsize =(8 ,2))plt . plot ( d_x , d_tri , lw =1.5 , color = ’ black ’)
plt . xlabel ( ’ time ’) # 横 軸 ラ ベ ル
plt . ylabel ( ’y ’)# 縦軸ラベルplt . title ( ’ Triangle ’)plt . show ()# - - - - - 方 形 波 ----d_rct = np . array ( ([ -1.0]*100+[1.0]*100)*2 )# 波形のプロット
pylab . figure ( figsize =(8 ,2))plt . plot ( d_x , d_rct , lw =1.5 , color = ’ black ’)
plt . xlabel ( ’ time ’) # 横 軸 ラ ベ ル
plt . ylabel ( ’y ’)# 縦軸ラベルplt . title ( ’ Rect ’)plt . show ()##########################################################
フーリエ変換########################################################### 周波数軸データ
n = len ( d_x )# データ長frq = n * np . fft . fftfreq (n , d =1.0)# - - - - - 正 弦 波 の 解 析 ----f_sin = np . fft . fft ( d_sin )f_sin_n = np . sqrt ( f_sin . real **2 + f_sin . imag **2 )# 振幅スペクトルのプロット
pylab . figure ( figsize =(8 ,2))plt . bar ( frq , f_sin_n , color = ’ black ’)
plt . xlim ( -8 ,8)plt . xlabel ( ’ Frequency ( Hz ) ’)
# 横軸ラベルplt . ylabel ( ’ Amplitude ’)# 縦軸ラベルplt . title ( ’ Amplitude spectrum of sin ’)plt . show ()

119

77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129

# - - - - - 鋸 歯 状 波 （ ノ コ ギ リ 波 ） の 解 析 ----f_saw = np . fft . fft ( d_saw )f_saw_n = np . sqrt ( f_saw . real **2 + f_saw . imag **2 )# 振幅スペクトルのプロット
pylab . figure ( figsize =(8 ,2))plt . bar ( frq , f_saw_n , color = ’ black ’)
plt . xlim ( -60 ,60)
plt . xlabel ( ’ Frequency ( Hz ) ’)
# 横軸ラベルplt . ylabel ( ’ Amplitude ’)# 縦軸ラベルplt . title ( ’ Amplitude spectrum of Saw ’)plt . show ()# - - - - - 三 角 波 の 解 析 ----f_tri = np . fft . fft ( d_tri )f_tri_n = np . sqrt ( f_tri . real **2 + f_tri . imag **2 )# 振幅スペクトルのプロット
pylab . figure ( figsize =(8 ,2))plt . bar ( frq , f_tri_n , color = ’ black ’)
plt . xlim ( -30 ,30)
plt . xlabel ( ’ Frequency ( Hz ) ’)
# 横軸ラベルplt . ylabel ( ’ Amplitude ’)# 縦軸ラベルplt . title ( ’ Amplitude spectrum of Triangle ’)plt . show ()# - - - - - 方 形 波 の 解 析 ----f_rct = np . fft . fft ( d_rct )f_rct_n = np . sqrt ( f_rct . real **2 + f_rct . imag **2 )# 振幅スペクトルのプロット
pylab . figure ( figsize =(8 ,2))plt . bar ( frq , f_rct_n , color = ’ black ’)
plt . xlim ( -60 ,60)
plt . xlabel ( ’ Frequency ( Hz ) ’)
# 横軸ラベルplt . ylabel ( ’ Amplitude ’)# 縦軸ラベルplt . title ( ’ Amplitude spectrum of Rect ’)plt . show ()##########################################################
フーリエ逆変換########################################################### - - - - - 方 形 波 の 逆 変 換 ----i_rct = np . fft . ifft ( f_rct )# 波形のプロット
pylab . figure ( figsize =(8 ,2))plt . plot ( d_x , i_rct . real , lw =1.5 , color = ’ black ’)
plt . xlabel ( ’ time ’) # 横 軸 ラ ベ ル
plt . ylabel ( ’y ’)# 縦軸ラベルplt . title ( ’ Rect ( Fourier inverse transform ) ’)plt . show ()解説：

11〜56 行目で，各種の波形データ（正弦波，鋸歯状波，三角波，方形波）を生成してそれらをプロットしている．
この部分により表示されるグラフを図 77 に示す．
これらの波形データは振幅 ±1.0 で周波数は 2Hz である．すなわち，最大の時刻は 1 で，その間に 2 回のサイクルを繰り返すものである．これらの波形データをフーリエ変換してプロットしているのが 62〜115 行目の部分である．
プロットに必要となる横軸（周波数スケール）のデータは 62〜63 行目で生成している．この部分の実行により得られる周波数領域のプロット（振幅スペクトル）を図 78 に示す．
（棒グラフの描画には matplotlib の bar 関数を使用している）
この結果，各波形とも周波数は 2Hz であるので，主たる成分である 2Hz の成分が最も強く表示されている．当然であるが正弦波はそれ自身が 1 つの周波数成分であるので 2Hz のみの成分から成ることがわかる．フーリエ変換の結果として得られる周波数の成分は，正負の両方の周波数領域にわたる形となる．

120

(a) 正弦波(b) 鋸歯状波（ノコギリ波）(c) 三角波(d) 方形波

図 77: 波形データ（時間の関数）(i) 正弦波(ii) 鋸歯状波（ノコギリ波）(iii) 三角波(iv) 方形波

図 78: 振幅スペクトル（周波数の関数）
この処理で得られた方形波の周波数領域のデータをフーリエ逆変換により再度時間領域のデータ列に戻している．
（121 行目）

それをプロットしているのが 124〜129 行目の部分であり，プロット結果を図 79 に示す．

図 79: フーリエ逆変換で再構成した方形波

3.1.19.3

プロットのアスペクト比の指定

matplotlib によるプロットにおいて，作図時のアスペクト比（縦横比）を指定するには pylab モジュールを読み込んで（プログラム npﬀt01.py の 5 行目）関数 ﬁgure を使用する．
書き方：

3.1.19.4

pylab.ﬁgure(ﬁgsize=(横, 縦))フーリエ変換を使用する際の注意

フーリエ変換で時間軸上の波形を周波数成分に変換する際には注意しなければならないことがある．離散的で有限な長さのデータをフーリエ変換すると，与えられたデータ列が繰り返されるものと見做した上での周波数成分が得られる．先のサンプルプログラムは，2Hz の単純な波形がそのまま繰り返されるという前提の信号解析であり，実際の信号解析ではそのようなことはあり得ない．すなわち，波形データを無思慮に切り出してフーリエ変換を実行すると，元の波形データには含まれない周波数成分が現れてしまう．これは，データ列の時間軸の両端を繋いだ形の波形が繰り返されていると見做した結果である．このような問題を解決するには，波形データを適切に切り出すための窓関数32を推定しながら，それを適用する形でフーリエ変換を実行しなければならない．
32 実際の周波数成分のみを適切に取り出すために，適切な時間領域のデータを切り出す関数．

121

信号解析のための具体的な工夫に関しては本書の範囲を超えるため割愛する．

3.1.20複素数の計算NumPy の各種関数やメソッドの多くは複素数の配列を扱うことができる．配列の実数成分，虚数成分には，当該配列の real，imag それぞれのプロパティを介してアクセスできる．
例．配列要素の実部，虚部へのアクセス

>>> a

←内容確認

Enter

←結果表示

array([0.+0.j, 0.+0.j, 0.+0.j])←全要素の実部を一度に設定

Enter>>> a.real = [1, 2, 3]
>>> a

←内容確認

Enter

←結果表示

array([1.+0.j, 2.+0.j, 3.+0.j])←全要素の虚部を一度に設定

Enter>>> a.imag = [4, 5, 6]
>>> a

←内容確認

Enter

←結果表示

array([1.+4.j, 2.+5.j, 3.+6.j])>>> a.real←全要素の実部を参照

Enter

←結果表示

array([1., 2., 3.])
3.1.20.1←複素数型のゼロの配列

Enter>>> a = np.zeros( 3, dtype=’complex’ )複素数の平方根要素が複素数である配列に対する sqrt 関数の値は複素数である．
例．複素数の平方根>>> np.sqrt(a)Enterarray([0.+1.j, 2.+0.j])←先頭の要素が −1 + 0j の複素数Enter>>> a = np.array([-1+0j,4])←各要素の平方根を求める←結果が複素数の配列として得られる要素が全て実数である配列に対して sqrt を実行すると，実数の範囲で計算する．
（次の例参照）
例．平方根の結果が複素数として得られないケース>>> a = np.array([-1,4])>>> np.sqrt(a)Enterarray([nan, 2.])

←要素が全て実数の配列

Enter←各要素の平方根を求める←実数とならない要素が nan（非数）になっている

参考．配列が実数か複素数化を判定すには isreal，iscomplex 関数を用いる．
例．配列が複素数かを調べる（先の例の続き）>>> np.iscomplex( np.array([-1+2j,3]) ).any()True
3.1.20.2Enter←「1 つでも複素数があるか」を検査←複素数を含む（複素数の配列である）
複素数のノルム

複素数のノルム（長さ，絶対値）は absolute 関数で求めることができる．
例．複素数のノルム>>> a = np.array([1+1j,3+4j,-2])>>> np.absolute(a)Enterarray([1.41421356, 5.
3.1.20.3Enter←複素数の配列←各要素のノルムを求める

, 2.

])

←計算結果

共役複素数

共役複素数を求めるには conj 関数（あるいはメソッド）を使用する．

122

例．共役複素数>>> a = np.array([1+1j,2-2j,3+3j,4-4j])
array([1.-1.j, 2.+2.j, 3.-3.j, 4.+4.j])>>> a.conj()←計算結果←各要素の共役複素数を求める（conj メソッド）Enter

array([1.-1.j, 2.+2.j, 3.-3.j, 4.+4.j])
3.1.20.4←複素数の配列←各要素の共役複素数を求める（conj 関数）

Enter>>> np.conj(a)Enter←計算結果（上と同じ）複素数の偏角（位相）複素数の偏角（位相）を求めるには angle 関数を使用する．
例．複素数の偏角（位相）Enter>>> a = np.array([1,1+1j,0+1j])>>> np.angle(a)array([0.

←複素数の配列←各要素の偏角を求める

Enter, 0.78539816, 1.57079633])←計算結果得られた要素の内，後ろ 2 つが π/4, π/2 となっていることを次の例で確認できる．
例．π/4, π/2 を求めて上の例と比較する>>> np.pi/4, np.pi/2

Enter← π/4, π/2 を求めてみる←計算結果(0.7853981633974483, 1.5707963267948966)
3.1.21行列，ベクトルの計算（線形代数のための計算）

NumPy は，数値（複素数）から成る行列（matrix）とベクトルを扱うための各種の機能を提供している．
3.1.21.1行列の和と積行列の和を求めるには通常の加算演算子 ’+’ が使用できる．
例．行列の和>>> a1 = np.array([[1,2],[3,4]])Enter←行列 a1 を生成>>> a2 = np.array([[5,6],[7,8]])Enter←行列 a2 を生成>>> a1 + a2

←加算の実行

Enter

←処理結果

array([[ 6, 8],[10, 12]])

通常の乗算演算子 ’*’ を用いて行列同士を計算すると，各要素毎の積を要素とする行列が得られる．行列同士の積を求めるには dot 関数を使用する．
例．行列の積（先の例の続き）>>> a1 * a2←’*’ の実行

Enter

←処理結果

array([[ 5, 12],[21, 32]])>>> np.dot(a1,a2)

Enter

←行列の積
←処理結果

array([[19, 22],
[43, 50]])dot 関数と同様の計算を行う @ 演算子もある．
例．@ 演算子による行列の積（先の例の続き）>>> a1 @ a2

Enter

←行列の積

array([[19, 22],
[43, 50]])
3.1.21.2←処理結果

単位行列，ゼロ行列，他全ての要素がゼロや 1 であるような行列や，単位行列を生成する例を示す．

123

例．全てゼロの配列の生成：

zeros 関数
←ゼロが 3 つの配列

Enter>>> np.zeros( 3 )←処理結果array([ 0., 0., 0.])← 2 行 3 列のゼロ行列Enter>>> np.zeros( (2,3) )←処理結果

array([[ 0., 0., 0.],[ 0., 0., 0.]])

既存の行列（配列）のサイズに合わせた形のゼロ行列を作成するには zeros like を使用する．
例．既存の行列と同じ形のゼロ行列Enter>>> a = np.array([[1,2,3,4],[5,6,7,8]])← 2 行 4 列のゼロ行列

array([[0, 0, 0, 0],[0, 0, 0, 0]])例．全て 1 の配列の生成：>>> np.ones( 3 )←行列 a と同じサイズのゼロ行列を作成

Enter>>> np.zeros like(a)ones 関数← 1 が 3 つの配列

Enter

←処理結果

array([ 1., 1., 1.])>>> np.ones( (2,3) )← 2 行 3 列の 1 ばかりの行列

Enter

←処理結果

array([[ 1., 1., 1.],
[ 1., 1., 1.]])
例．単位行列の生成：

identity 関数>>> np.identity( 5 )← 5 × 5 の単位行列

Enterarray([[ 1., 0., 0., 0., 0.],[ 0., 1., 0., 0., 0.],[ 0., 0., 1., 0., 0.],[ 0., 0., 0., 1., 0.],[ 0., 0., 0., 0., 1.]])3.1.21.3← 2 行 4 列の行列 a←処理結果

行列の要素を全て同じ値にする

既存の配列の全ての要素を同じ値で置き換えるには ﬁll メソッドを用いる．次の例は，全ての要素が 1 である配列を作成した後，全要素を 3.1416 で置き換えるものである．
例．指定した値で既存の配列の要素を全て置き換える>>> a = np.ones( (3,4) )>>> a← 3 行 4 列の 1 ばかりの行列を生成

Enter←内容の確認

Enter

←結果表示

array([[ 1., 1., 1., 1.],
[ 1., 1., 1., 1.],
[ 1., 1., 1., 1.]])>>> a.fill( 3.1416 )
>>> a

Enter

Enter

全ての要素を 3.1416 で満たす
←内容の確認array([[ 3.1416, 3.1416, 3.1416, 3.1416],[ 3.1416, 3.1416, 3.1416, 3.1416],[ 3.1416, 3.1416, 3.1416, 3.1416]])←結果表示」

参考）疎な行列の作成
疎な行列（スパース行列：sparse matrix ）33 を生成するには，予め 0 ばかりの要素の行列を生成しておき，添字を指定して要素の値を設定するという方法が良い．
全要素が同じ値である行列を新規に作成するには full 関数を用いる．

33 大部分の要素が 0 であるような行列．

124

例．全要素が 7 である行列の新規作成>>> a = np.full( (3,6), 7 )>>> a←内容の確認

Enter

←結果表示

array([[7, 7, 7, 7, 7, 7],[7, 7, 7, 7, 7, 7],[7, 7, 7, 7, 7, 7]])3.1.21.4← 3 行 6 列の 7 ばかりの行列を生成Enter

ベクトルの内積

dot 関数に 1 次元配列（ベクトル）を与えると，それらの内積を計算する．
例．ベクトルの内積>>> v1 = np.array( [1,2,3] )Enter←ベクトル v1 = (1, 2, 3) の作成>>> v2 = np.array( [4,5,6] )Enter←ベクトル v2 = (4, 5, 6) の作成>>> np.dot(v1,v2)
32←内積 v1 · v2 の計算

Enter

←内積の値

inner 関数でも内積を求めることができる．
例．inner 関数による内積の計算（先の例の続き）

32
3.1.21.5←内積 v1 · v2 の計算

Enter>>> np.inner(v1,v2)←内積の値

対角成分，対角行列

diag 関数を用いると，行列の対角成分を抽出することができる．
例．行列の対角成分の抽出>>> a = np.arange(1,10).reshape(3,3)>>> a←サンプル行列の作成←内容の確認

Enter

←結果表示

array([[1, 2, 3],[4, 5, 6],[7, 8, 9]])>>> np.diag(a)Enter←対角成分の抽出

Enter

array([1, 5, 9])←結果表示（対角成分の配列が得られている）

diag にキーワード引数 ‘k=開始インデックス’ を与えると，対角成分を抽出する開始位置（先頭行のインデックス）を指定することができる．
例．開始位置を指定して対角成分を抽出（先の例の続き）>>> np.diag(a,k=1)

Enter←先頭行のインデックス 1（2 番目の要素）から抽出←結果表示

array([2, 6])>>> np.diag(a,k=2)

Enter

←結果表示

array([3])>>> np.diag(a,k=3)←先頭行のインデックス 2（3 番目の要素）から抽出

Enter

array([], dtype=int32)←先頭行のインデックス 3（存在しない）から抽出←結果表示（空）diag 関数の引数に 1 次元の配列やリストを与えると，それを対角成分とする対角行列を生成する．
例．対角行列の生成>>> np.diag([11,22,33])
array([[11, 0, 0],[ 0, 22, 0],[ 0, 0, 33]])Enter←対角成分を与えて対角行列を生成
←結果表示

125

3.1.21.6

行列の転置

行列を転置するには transpose 関数を使用する．
例．行列の転置>>> a = np.array([[1,0,-2],[5,2,-3],[2,-1,3]])
Enter←内容の確認array([[ 1, 0, -2],
[ 5, 2, -3],
[ 2, -1, 3]])

←結果表示

>>> a

>>> np.transpose(a)← 3 行 3 列の行列を生成←転置の実行 (1)

Enter

←処理結果

array([[ 1, 5, 2],[ 0, 2, -1],[-2, -3, 3]])>>> a.TEnter←転置の実行 (2)

Enter

←処理結果

array([[ 1, 5, 2],[ 0, 2, -1],[-2, -3, 3]])

この例にあるように，T プロパティからも転置行列を取り出すことができる．

3.1.21.7

行列式と逆行列例．行列式を求める（先のつづき）：>>> np.linalg.det(a)det 関数

Enter

←結果表示

20.999999999999989
例．逆行列を求める（つづき）：>>> np.linalg.inv(a)←行列式を求める

inv 関数←逆行列を求めるEnter

array([[ 0.14285714, 0.0952381 , 0.19047619],[-1.
, 0.33333333, -0.33333333],[-0.42857143, 0.04761905, 0.0952381 ]])3.1.21.8←結果表示

固有値と固有ベクトル行列を転置するには linalg パッケージの eig 関数を使用する．
例．行列の固有値と固有ベクトルを求める（つづき）：>>> (e,ev) = np.linalg.eig(a)
>>> e

Enter

Enter

eig 関数←固有値と固有ベクトルを求める←固有値の配列の内容を確認

array([ 0.82433266+2.03631557j, 0.82433266-2.03631557j, 4.35133469+0.j ])>>> ev

Enter

←結果表示

←固有ベクトルの配列の内容を確認

array([[-0.01760985-0.35786298j, -0.01760985+0.35786298j, -0.21323532+0.j ],[-0.85880917+0.j, -0.85880917-0.j, -0.90931800+0.j ],[-0.36590772-0.01350281j, -0.36590772+0.01350281j, 0.35731146+0.j ]])←結果表示

固有値は複素数のスカラーであり，与えられた行列が固有値を持つ場合はそれらを配列にして返す．個々の固有値にはそれぞれ対応する固有ベクトルがあり，それを行列（配列）にしたものを返す．

eig 関数は固有値と固有ベクトルを次のような形式のタプルで返す．
(固有値の配列, 固有ベクトルの配列)「固有ベクトルの配列」の各列が固有ベクトルとなっている．
注）eig 関数が返したタプルにおいて，固有値と固有ベクトルは順番に対応する．すなわち，固有値の配列の第 n 番目の固有値に対する固有ベクトルは，固有ベクトルの配列の第 n 番目の列である．従って，指定した固有値に対応する
固有ベクトルを取り出すには，固有ベクトルの配列を転置した後に添え字を指定して取り出すといった作業が必要と
なる．

126

3.1.21.9

行列のランク行列のランクを求めるには linalg パッケージの matrix rank 関数を使用する．
例．行列のランクを求める：

matrix rank 関数
Enter>>> a1 = np.array([[2,-1,5],[-3,0,7],[9,4,-6]])>>> a1←内容の確認

Enter

←結果表示

array([[ 2, -1, 5],[-3, 0, 7],[ 9, 4, -6]])>>> np.linalg.matrix rank( a1 )3

←ランクの算出

Enter

←結果表示
←内容の確認

Enter

←結果表示

array([[ 2, -1, 5],[ -3, 0, 7],[ -4, 2, -10]])>>> np.linalg.matrix rank( a2 )2
3.1.21.10←行列 a2 を生成

Enter>>> a2 = np.array([[2,-1,5],[-3,0,7],[-4,2,-10]])>>> a2←行列 a1 を生成←ランクの算出

Enter

←結果表示
複素共役行列複素共役行列を求めるには conjugate 関数を使用する．
例．複素共役行列を求める：

conjugate 関数
Enter>>> ca = np.array([[1-2j,0],[0,-3+1j]])>>> ca←内容の確認

Enter

←結果表示

array([[ 1.-2.j, 0.+0.j],[ 0.+0.j, -3.+1.j]])>>> np.conjugate(ca)←複素共役行列を求める

Enter

←結果表示

array([[ 1.+2.j, 0.-0.j],[ 0.-0.j, -3.-1.j]])
3.1.21.11←行列 ca を生成

エルミート共役行列

エルミート共役行列を求めるには conjugate 関数（conj 関数と同じ）と転置を組み合わせる．
例．エルミート共役行列を求める>>> ca = np.array([[1-2j,-5+7j],[4-6j,-3+1j]])>>> ca←行列 ca を生成←内容の確認Enter

array([[ 1.-2.j, -5.+7.j],[ 4.-6.j, -3.+1.j]])>>> np.conjugate( ca.T )←結果表示←エルミート共役行列を求める

Enter

array([[ 1.+2.j, 4.+6.j],[-5.-7.j, -3.-1.j]])
3.1.21.12

Enter

←結果表示

ベクトルのノルムベクトルのノルムを求めるには linalg パッケージの norm 関数を使用する．
例．ベクトルのノルムを求める：>>> v = np.array([1,1])>>> np.linalg.norm(v)1.4142135623730951

norm 関数
Enter
Enter

←ベクトル v を生成←ノルム（長さ）を求める

←結果表示

127

3.1.22

入出力：配列オブジェクトのファイル I/O

実際のデータ解析においては扱うデータのサイズが大きい場合が多く，適宜ファイルに出力保存したり，それを読み込んで処理をするという流れになる．ここでは，NumPy で扱うデータをファイルに保存する，あるいはファイルから読み込む方法について説明する．
配列オブジェクトのファイル I/O において 3 種類の形式を選ぶことができる．1 つはテキスト形式であり，CSV や

TSV などの形式に沿った入出力により，他の処理系とのデータ連携が容易になる．
3.1.22.1

テキストファイルへの保存

random パッケージの rand 関数を使用して大きな乱数表を作成して，それを CSV 形式34 のテキストファイルとして保存する例を示す．
例．100 行 10 列の一様乱数を CSV データとして保存する>>> rnd = np.random.rand( 100, 10 )←乱数表を生成Enter>>> np.savetxt(’random.csv’,rnd,delimiter=’,’)Enter← CSV データとして保存>>>
この例では savetxt 関数を使用して配列オブジェクトをファイルに保存している．この関数の使用方法は次の通りで
ある．
書き方：

np.savetxt(出力先ファイル名, 配列オブジェクト, delimiter=区切り文字)

この方法で保存したテキストファイル ’random.csv’ を Microsofot 社の表計算ソフト Excel で開いた例を図 80 に示す．

図 80: Microsoft 社の表計算ソフト Excel でファイルを開いたところ■ 保存時の書式指定
保存する値の書式（桁数や型）を指定するには，savetxt 関数にキーワード引数 ‘fmt=’ を与える．これに関して例を挙げて説明する．
サンプルとして次のような配列データ r を用意する．
例．サンプルデータの作成（つづき）>>> np.random.seed(8)Enter← seed の設定35>>> r = np.random.normal( 50, 30, (3,3) )>>> print( r )

Enter

Enter

← 3 行 3 列の乱数配列←内容確認[[ 52.7361415 82.738482 -8.40910927][ 8.40951403 -18.89474723 122.2950291 ][101.83508506 116.13668854 73.84482918]]←内容表示

この配列の各列に書式を指定して CSV ファイルとして保存する例を示す．
34 コンマ ’,’ で区切られたテキスト形式の表データである．詳しくは IETF が定める技術仕様 RFC 4180 を参照のこと．
35 p.91「3.1.13.4 乱数の seed について」を参照のこと．

128出力結果のファイル：test01.csv

例．書式付き保存（つづき）

Enter>>> np.savetxt(’test01.csv’,r,delimiter=’,’,
...

1
2
3

Enter

fmt=[’%3d’,’%5.1f’,’%.2f’])

52 , 82.7 , -8.41
8 , -18.9 ,122.30
101 ,116.1 ,73.84

この例のように，キーワード引数 ‘fmt=’ には保存する配列の各列に対する書式設定のリストを与える．小数点数の書式は’%値の桁数. 小数点以下の桁数 f ’とし，整数の書式は’%値の桁数 d’とする．
「値の桁数」を省略すると桁数は自動的に調整される．
■ ヘッダーを付けて保存する
出力するファイルの先頭に見出し行を付けるには，savetxt 関数にキーワード引数 ’header=’ を与える．これに関して例を挙げて説明する．
例．ヘッダーを付けて保存（つづき）

出力結果のファイル：test02.csv>>> np.savetxt(’test02.csv’,r,delimiter=’,’,

Enter

...

encoding=’utf-8’, Enter ←エンコーディングの指定...

fmt=[’%3d’,’%5.1f’,’%.2f’],

Enter

...

header=’1 列目,2 列目,3 列目’)

Enter

1
2
3
4

# 1 列 目 ,2 列 目 ,3 列 目
52 , 82.7 , -8.41
8 , -18.9 ,122.30
101 ,116.1 ,73.84

この例では，日本語の見出し行を出力するためにエンコーディング指定「encoding=’utf-8’」を与えている．ヘッダー
行はデータとは無関係であるため，出力されたファイルのヘッダー行の先頭にはコメント行であることを意味する記号「#」が自動的に付けられる．ヘッダー行の先頭に「#」を付けずに出力するにはキーワード引数「comments=”」を与える．これに関する例を示す．
例．ヘッダー先頭に「#」を付けずに保存（つづき）>>> np.savetxt(’test03.csv’,r,delimiter=’,’,

Enter

出力結果のファイル：test03.csv
1
2
3
4

Enter

...

encoding=’utf-8’,...

fmt=[’%3d’,’%5.1f’,’%.2f’],

Enter

...

header=’1 列目,2 列目,3 列目’,

Enter

...

comments=’’ )Enter

1 列 目 ,2 列 目 ,3 列 目
52 , 82.7 , -8.41
8 , -18.9 ,122.30
101 ,116.1 ,73.84←「#」を付けない指定■ 数値以外のデータの保存
統計学におけるカテゴリデータ36 は非数値の文字列（ラベル）として表現されることが一般的であり，そのような要素から成る配列をファイルに出力するには書式を’%s’とする．文字列の配列をファイルに出力する例を以下に示す．
例．サンプルデータ（文字列の配列）の作成>>> catd = np.array([[’ みかん’,’orange’],[’ りんご’,’apple’],[’ バナナ’,’banana’]])Enter>>> print( catd )Enter[[’ みかん’ ’orange’][’ りんご’ ’apple’][’ バナナ’ ’banana’]]←文字列の配列←内容確認←配列の内容例．サンプルデータのファイルへの出力（先の例の続き）>>> np.savetxt(’catd.csv’, catd, delimiter=’,’, encoding=’utf-8’, fmt=’%s’,
header=’Japanese,English’, comments=’’)Enter←ファイルへの出力
36 「カテゴリカルデータ」（categorical data）とも呼ばれる．

129

これを実行した結果，右のようなファイル ‘catd.csv’

出力結果のファイル：catd.csvが作成される．

3.1.22.2

1
2
3
4

Japanese , English
み か ん , orange
り ん ご , apple
バ ナ ナ , banana

テキストファイルからの読み込み関数 loadtxt を使用するとテキストファイルからデータを読み込むことができる．
例．CSV 形式のデータを読み込む（つづき）>>> rnd2 = np.loadtxt(’random.csv’,delimiter=’,’)>>> rnd == rnd2

Enter

Enter

← CSV データの読み込み←元の配列との比較を試みる

array([[ True, True, True, True, True, True, True, True, True, True], ←比較結果[ True, True, True, True, True, True, True, True, True, True],：（途中省略）：[ True, True, True, True, True, True, True, True, True, True]], dtype=bool)
この実行結果から，保存したデータを再度読み込んだものが，元の配列と同じ内容であることが検証できた．
（行列同士の比較に関しては「3.1.23 行列の検査」を参照のこと）

loadtxt 関数の使用方法は次の通りである．
書き方 (1)：

np.loadtxt(入力元ファイル名, delimiter=区切り文字)

この関数は，読み込んだデータを配列オブジェクトとして返す．
■ 見出し行のある CSV 形式データを読み込む際の注意

CSV 形式データは 1 行目が見出し行となっていることがあり，そのようなデータを先の方法で読み込むとエラーが発生する．見出し行には NumPy の配列として扱えない型（文字列など）のデータが使用されることが多いというだ
けでなく，そもそも計算の対象とするデータではないので，見出し行は読み込みの際に無視する必要がある．次に示
すように，loadtxt 関数のキーワード引数 skiprows= に整数値を指定すると，入力ファイルの先頭から指定した行数の読み込みを無視することができる．
書き方 (2)：

np.loadtxt(入力元ファイル名, delimiter=区切り文字, skiprows=スキップする行数 )入力データの先頭 1 行が見出し行となっている場合は skiprows=1 を指定することで，正しく入力処理が行われる．
■ 数値以外のデータの読込み
数値以外のデータ（文字列）から構成されるカテゴリデータなどを読み込む際は loadtxt にキーワード引数「dtype=データタイプ」を与える．読み込むデータが Unicode 文字である場合は「dtype=’U’」とする．先の例で作成した CSV データ ‘catd.csv’ を読み込む例を示す．
例．文字列から成る CSV ファイルの読込み>>> catd2 = np.loadtxt(’catd.csv’,delimiter=’,’, encoding=’utf-8’, skiprows=1,
dtype=’U’ )Enter←読込み処理>>> print( catd2 )←内容確認[[’ みかん’ ’orange’][’ りんご’ ’apple’][’ バナナ’ ’banana’]]←配列の内容■ 特定の列（カラム）の読込み

CSV ファイルの内容の内，指定した特定の列（カラム）のみを抽出して読み込むことができる．作成したサンプル
データを用いてこのことを例示する．

130

例．サンプルデータの作成

Enter>>> for i in range(10):...

←ここからサンプルデータの作成

Enter>>> rdat = np.zeros( (5,10) )rdat[:,i] = np.arange(i*10,i*10+5)← for 文の終了

Enter

...

Enter

←サンプルデータの内容確認Enter>>> print( rdat )[[ 0. 10. 20. 30. 40. 50. 60. 70. 80. 90.]
[ 1. 11. 21. 31. 41. 51. 61. 71. 81. 91.]
[ 2. 12. 22. 32. 42. 52. 62. 72. 82. 92.]
[ 3. 13. 23. 33. 43. 53. 63. 73. 83. 93.]
[ 4. 14. 24. 34. 44. 54. 64. 74. 84. 94.]]← 5 行 10 列の配列>>> np.savetxt(’rdat01.csv’,rdat, delimiter=’,’, fmt=’%3d’ )Enter←ファイルへの保存

この処理により次のような CSV ファイル ‘rdat01.csv’ が出来上がる．
出力結果のファイル：rdat01.csv
1
2
3
4
5

0,
1,
2,
3,
4,

10 ,
11 ,
12 ,
13 ,
14 ,

20 ,
21 ,
22 ,
23 ,
24 ,

30 ,
31 ,
32 ,
33 ,
34 ,

40 ,
41 ,
42 ,
43 ,
44 ,

50 ,
51 ,
52 ,
53 ,
54 ,

60 ,
61 ,
62 ,
63 ,
64 ,

70 ,
71 ,
72 ,
73 ,
74 ,

80 ,
81 ,
82 ,
83 ,
84 ,

90
91
92
93
94

次に，このファイルから特定の列（カラム）を抽出して読み込む例を示す．
例．‘rdat01.csv’ からインデックス位置が 1（左から 2 番目）の列を読み込む（先の例の続き）>>> r1 = np.loadtxt(’rdat01.csv’, delimiter=’,’, usecols=1 ) Enter ←列指定読込み
Enter>>> print( r1 )
[10.

11.

12.

13.

←読み取り結果の確認

14.]

←結果表示

この例のように，loadtxt 関数にキーワード引数

usecols=列のインデックスを与えると，「列のインデックス」に指定した列のみを読み込んで一次元配列の形で返す．また，このキーワード引数には複数のインデックスをリストや配列の形で与えることも可能であり，その場合は，指定した複数の列をまとめて読み込むことができる．
例．複数の列をまとめて読み込む（先の例の続き）>>> r135 = np.loadtxt(’rdat01.csv’, delimiter=’,’, usecols=[1,3,5] ) Enter ←複数列の読込み>>> print( r135 )[[10. 30. 50.]
[11. 31. 51.]
[12. 32. 52.]
[13. 33. 53.]
[14. 34. 54.]]

Enter←読み取り結果の確認← CSV ファイルの中のインデックス位置 1,3,5 の列が得られている

この例のように，loadtxt 関数にキーワード引数

usecols=[n1 , n2 , n3 , · · ·]を与えると，n1 , n2 , n3 , · · · のインデックス位置の列を抽出して二次元配列として返す．

3.1.22.3

バイナリファイルへの I/O関数 save, load を使用することでバイナリファイルに対する I/O ができる．

131

例．バイナリファイルに対する I/O（つづき）>>> np.save(’random.npy’,rnd)>>> rnd2 = np.load(’random.npy’)>>> rnd == rnd2

Enter

←配列 rnd をファイル ’random.npy’ に保存Enter←ファイル ’random.npy’ から読み込み

Enter←元の配列との比較を試みる

array([[ True, True, True, True, True, True, True, True, True, True], ←比較結果[ True, True, True, True, True, True, True, True, True, True],：（途中省略）：[ True, True, True, True, True, True, True, True, True, True]], dtype=bool)
この例でも保存と読み込みが正常に行われたことがわかる．
（行列同士の比較に関しては「3.1.23 行列の検査」を参照のこと）

save と load の使用方法：
np.save(出力先ファイル名, 配列オブジェクト)
np.load(入力元ファイル名)load 関数は読み込んだデータを配列オブジェクトとして返す．
3.1.22.4

データの圧縮保存と読み込みサイズの大きな配列オブジェクトを複数取り扱う場合，それら配列をまとめて圧縮処理37 して，1 つのファイルとして保存することができる．
例．配列オブジェクトの圧縮保存と読み込み（つづき）>>> np.savez(’random.npz’,name1=rnd)>>> arc = np.load(’random.npz’)>>> arc[’name1’]==rnd

Enter

Enter

Enter

←配列 rnd をファイル ’random.npz’ に圧縮保存←ファイル ’random.npy’ から読み込み←元の配列との比較を試みる

array([[ True, True, True, True, True, True, True, True, True, True], ←比較結果[ True, True, True, True, True, True, True, True, True, True],：（途中省略）：[ True, True, True, True, True, True, True, True, True, True]], dtype=bool)
この例でも保存と読み込みが正常に行われたことがわかる．
（行列同士の比較に関しては「3.1.23 行列の検査」を参照のこと）
圧縮保存の使用方法：

np.savez(出力先ファイル名, データ名=配列オブジェクト, …)
np.load(入力元ファイル名)
圧縮データを load 関数で読み込むと NpzFile オブジェクトが返される．この NpzFile オブジェクトに添え字として[データ名]を付けることで，配列オブジェクトを参照することができる．先の例ではデータ名として ’name1’ というものを与えて配列 rnd を ’random.npz’ というファイルに保存している．それを読み込んで arc という NpzFile オ
ブジェクトを得た後，データ名を付加して arc[’name1’] として配列オブジェクトを参照している．このような方法で，複数の配列オブジェクトに異なるデータ名を付けて圧縮保存することができる．

37 ZIP フォーマットで圧縮している．複数のデータをまとめて管理するアーカイブの機能も備えている．

132

3.1.22.5

配列をバイトデータに変換して入出力に使用する

配列オブジェクトに対して tobytes メソッドを実行することで，それをバイト列に変換することができる．
例．配列をバイト列に変換する>>> a = np.array( [1,2,3,4,5,1,2,3,4,5], dtype=’int16’ )Enter>>> b = a.tobytes()>>> len(b)Enter← 1 次元配列を作成←それをバイト列のデータに変換する←バイト列の長さを調べるEnter← 20 バイトである

20>>> type(b)←型を調べるEnter←バイト列であることが確認できる<class ’bytes’>

この例で得られたバイト列 b をファイルに保存する例を示す．
例．作成したバイト列をファイルに保存する（先の例の続き）>>> fo = open( ’array01.dat’, ’wb’ )>>> fo.write(b)Enter←出力用ファイルをバイナリモードで開く（作成する）←そのファイルに対して，先に作成したバイト列 b を出力する

Enter← 20 バイト出力した

20>>> fo.close()←ファイルを閉じる

Enter

この処理で，バイト列 b がファイル ’array01.dat’ に出力される．
次に，改めてこのファイルから内容を読み取って，それを配列オブジェクトに変換する処理の例を示す．
例．バイナリデータを読み込んで配列オブジェクトにする（先の例の続き）>>> fi = open( ’array01.dat’, ’rb’ )>>> buf = fi.read()>>> fi.close()

Enter

Enter

Enter

←そのファイルからバイトデータを（全て）読み取る←ファイルを閉じる>>> a2 = np.frombuffer( buf, dtype=’int16’ )>>> print( a2 )Enter

[1 2 3 4 5 1 2 3 4 5]

←ファイルを入力用にバイナリモードで開く

Enter←読み取ったバイトデータを配列に変換する←出来上がった配列を表示する←結果表示：最初に作成した配列と同じものが得られている

この例で示したように frombuﬀer を使用することで，バイト列を配列オブジェクトに変換することができる．
書き方：

frombuﬀer( バイト列, dtype=データ型 )結果として，最初に作成した配列オブジェクトをファイルとして保存し，それを読み取って別の配列オブジェクトとして復元することができていることがわかる．
応用例）

frombuﬀer を使ってバイト列を配列に変換する方法を応用すると，WAV 形式サウンドファイルから波形データを読み取って，それを NumPy の配列オブジェクトに変換する38 ことができる．

38 これに関しては拙書「Python3 入門」で解説しています．

133

3.1.23行列の検査

先に示した例のように，2 つの行列（配列）の要素が全て等しいかどうかを調べる場合，比較演算子 ’==’ を用いると，各要素の比較結果である真理値の行列が得られる．この比較結果の行列（真理値の行列）に対して all メソッドを使用すると全て True かどうかを更に判定することができる．
例．行列の要素が全て等しいかどうかの判定（つづき）>>> (rnd == rnd2).all()True←全ての要素が True か判定

Enter

全ての要素が True である

all の他にも，「少なくとも 1 つの要素が True である」ことを検査する any メソッドもある．
3.1.23.1

全て真，少なくとも 1 つは真：

all，any

all メソッドは配列の要素が全て真（True）の場合に真を返す．
例．all メソッドによる「全て真である」判定>>> b = np.full( (2,3), True )
>>> b

←内容確認

Enter

←配列の内容array([[ True, True, True],[ True, True, True]])>>> b.all()True←全て True の 2 次元配列

Enter

Enter

←全て真（True）かの検査←検査結果

当然のことではあるが，配列の要素に 1 つでも False が含まれると all の結果は偽（False）となる．
例．1 つの偽を含む配列に対する all（先の例の続き）>>> b[0,1] = False>>> b←配列の要素の 1 つを False にする

Enter

←内容確認

Enter

←配列の内容（False が含まれている）

array([[ True, False, True],[ True, True, True]])>>> b.all()
False

Enter

←全て真（True）かの検査←検査結果

any メソッドは配列の要素が 1 つでも真（True）を含む場合に真を返す．
例．any メソッドによる「真が含まれる」判定>>> b = np.full( (2,3), False )
>>> b

←内容確認

Enter

array([[False, False, False],[False, False, False]])>>> b.any()
False

Enter

←真（True）が含まれるかの検査

Enter←配列の要素の 1 つを True にする

←内容確認

Enter

array([[False, True, False],[False, False, False]])>>> b.any()
True←配列の内容←検査結果>>> b[0,1] = True>>> b

←全て False の 2 次元配列

Enter

Enter

←配列の内容（True が含まれている）←真（True）が含まれるかの検査←検査結果

any も行列の比較に応用することができる．次の例は 2 つの行列を比較するもので，対応する位置の要素が等しいものが 1 箇所でもあるかどうかを判定するものである．

134

例．any メソッドを使用した「少なくとも 1 つの要素が True である」判定>>> a1 = np.array([[1,2],[3,4]])Enter←配列 a1 を生成>>> a2 = np.array([[1,2],[5,4]])Enter←配列 a21 を生成>>> a3 = np.array([[-1,-2],[-5,-4]])>>> (a1==a2).all()←配列 a3 を生成← a1 と a2 の要素が全て等しいか検査

Enter←異なるものがあることがわかる

False>>> (a1==a2).any()← a1 と a2 の要素で互いに等しいものが 1 つでもあるかを検査

Enter←等しい要素があることがわかる

True>>> (a2==a3).any()← a2 と a3 の要素で互いに等しいものが 1 つでもあるかを検査

Enter←等しい要素がないことがわかる

False
3.1.24Enter

配列を処理するユーザ定義関数の実装について

NumPy は配列に対する処理を実行する便利な関数やメソッドを提供しているが，ユーザ独自の関数の実装が求められることも多い．素朴な方法としては，NumPy の配列の要素 1 つ 1 つに対して施す処理を for などの文で繰り返し実行するというものが挙げられる．ただし for 文による繰り返し処理は実行時間が大きくなることも多く，またプ
ログラムの可読性が低下する原因にもなる．ここでは，ユーザ定義関数の実装において実行時間と可読性の問題を小さくするための方法について紹介する．
■ for, map, vectorize の比較
次のような関数を考える．

sin(x) +

1
1
1
1
1
1
1
sin (2x) + sin (3x) + sin (4x) + sin (5x) + sin (6x) + sin (7x) + sin (8x)
2
3
4
5
6
7
8

これはノコギリ波（鋸歯状波）の波形を近似的に表現した関数である．この関数を定義域となる配列データに対して実行することを考える．次に示すサンプルプログラム npfunctest01.py は [−20, 20) の範囲の 0.0004 刻みのデータ列

x に対して，上に示した関数を fun として定義して適用するものである．
プログラム：npfunctest01.py
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

# coding : utf -8# モジュールの読み込み
import numpy as np
import matplotlib . pyplot as plt
import timex = np . arange ( -20 ,20 ,0.0004)
n = len ( x )print ( ’ 要 素 数 ： ’ , n )# 定義域データの配列# 要素の数##############################################################sin ( x ) + 1/2* sin (2* x ) + 1/3* sin (3* x ) 求 め る############################################################### 要素に対する計算を実行する関数
def fun ( x ):return np . sin ( x ) + 1.0/2.0* np . sin ( x *2.0) + \1.0/3.0* np . sin ( x *3.0) + 1.0/4.0* np . sin ( x *4.0) + \1.0/5.0* np . sin ( x *5.0) + 1.0/6.0* np . sin ( x *6.0) + \1.0/7.0* np . sin ( x *7.0) + 1.0/8.0* np . sin ( x *8.0)#----- 実 行 時 間 テ ス ト(1) ---------------------print ( ’ 方 法 1 ： f o r に よ る 繰 り 返 し ’)
t1 = time . time ()ly1 = []
for i in range ( n ):ly1 . append ( fun ( x [ i ]) )y1 = np . array ( ly1 )t = time . time () - t1
print (t , ’ 秒 \ n ’)plt . plot (x , y1 )

135

33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55

plt . show ()#----- 実 行 時 間 テ ス ト(2) ---------------------print ( ’ 方 法 2 ： m a p 関 数 に よ る 方 法 ’)
t1 = time . time ()ly2 = map ( fun , x )y2 = np . array ( list ( ly2 ))# この時に計算が実行される
t = time . time () - t1
print (t , ’ 秒 \ n ’)plt . plot (x , y2 )plt . show ()#----- 実 行 時 間 テ ス ト(3) ---------------------print ( ’ 方 法 3 ： np . v e c t o r i z e に よ る 方 法 ’)
t1 = time . time ()vfun = np . vectorize ( fun )# 関数が「ベクトル化」される
y3 = vfun ( x )# 計算実行t = time . time () - t1
print (t , ’ 秒 ’ )plt . plot (x , y3 )plt . show ()解説：

7 行目で定義域のデータを生成している．16〜20 行目で関数 fun を定義しており，この関数を後の行で定義域の全要素に対して実行する．

25〜28 行目では for 文を用いて計算を行い，同様の計算を 38〜39 行目では map 関数を使用して実行している．49
行目では NumPy の vectorize 関数を使用して，関数 fun を vfun に変換している．この結果得られた vfun は NumPyの配列の全要素に対して一度に処理を施し，結果の値を要素として持つ配列を返す．
このプログラムを実行した結果図 81 のようなグラフが表示される．
（3 回表示される）

図 81: グラフの表示（3 回表示される）プログラムの実行に伴って次のように標準出力に出力され，for による方法，map による方法，vectorize による各方法での実行時間がわかる．

136

例．実行結果の出力例
要素数： 100000
方法 1：for による繰り返し
2.2479827404022217 秒
方法 2：map 関数による方法
1.8539953231811523 秒
方法 3：np.vectorize による方法
1.2290003299713135 秒

for による実行が最も時間がかかり，map 関数による実行はそれよりも若干早いことがわかる．NumPy の vectorize
関数でベクトル化された関数による実行が最も早い（for と比較して約 2 倍の速度である）ことがわかる．ただし，計算対象のデータの要素の数や型，実行する関数の定義，さらには計算機環境によって実行時間は変わるので注意が必要である．

3.1.25行列の計算を応用した計算速度の改善の例

多くの場合において NumPy の行列計算の実行速度は非常に早い．計算量が多くなる処理に関しては，行列の計算が応用できるように極力工夫すべきである．先に示したプログラム npfunctest01.py は行列同士の積の計算を応用できる例であり，応用したプログラムを npfunctest02.py に示す．
プログラム：npfunctest02.py
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

# coding : utf -8# ライブラリの読み込み
import numpy as np
import matplotlib . pyplot as plt
import timex = np . arange ( -20 ,20 ,0.0004)
n = len ( x )print ( ’ 要 素 数 ： ’ , n )# 定義域データの配列# 要素の数##############################################################
行列の計算を応用したプログラム##############################################################
t1 = time . time ()# 時間計測開始# - - - - - こ こ か ら - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -## sin ( n * x ) の 配 列 を n =1 〜 8 に つ い て 作 成 し て 束 ね る 処 理 と## 1/ n の 配 列 を 作 成 す る 処 理## - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -#M = [];
r = []
for n in range (1 ,9):y = np . sin ( n * x )# 各 n に つ い て s i n (n*x) の 配 列 を 作 成
M . append ( y )r . append (1/ n )# 1/ n を 作 成
R = np . array ( r )# 1/ n の 配 列 を N u m P y の 配 列 に 変 換
A = np . vstack ( M )# sin ( n * x ) の 配 列 を 2 次 元 配 列 に 合 成# - - - - - こ こ ま で - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -#V = np . dot ( A .T , R )t2 = time . time ()print ( t2 - t1 , ’ 秒 ’ )# 行列の積を利用して波形合成# 時間計測終了

plt . plot (x , V . T )plt . show ()# グラフをプロット

このプログラムを実行すると図 81 と同じグラフが表示されるが，同一の計算機環境（CPU:Intel Core i7 5500U

2.4GHz）における実行時間が 0.0312 秒であった．これは npfunctest01.py の np.vectorize による方法に比べても 40
倍以上の計算速度である．

137

3.1.25.1

要素の型によって異なる計算速度

配列の要素の型によって計算速度が異なることがあるので注意が必要である．ここでは，500 × 500 のサイズの行列同士の積を求めるのに要する時間について例を挙げて考える．各種データ型毎に行列の積を計算する時間を測定する．
例．int64 の場合の計算時間>>> a1i = np.arange( 0, 500000, 2, dtype=’int64’ ).reshape( (500,500) ) Enter←行列 a1i>>> a2i = np.arange( 1, 500000, 2, dtype=’int64’ ).reshape( (500,500) ) Enter←行列 a1i>>> import time

←時間計測用に time モジュールを読み込む

Enter>>> t1 = time.time()>>> a3i = np.dot(a1i,a2i)>>> t2 = time.time()>>> print(t2-t1)

←開始時間

Enter

←行列の積の計算

Enter

←終了時間

Enter

←経過時間

Enter

←単位は秒

0.169266939163208

例．ﬂoat64 の場合の計算時間（先の例の続き）>>> a1f = a1i.astype(’float64’)

Enter← ﬂoat64 の行列 a1f を作成>>> a2f = a2i.astype(’float64’)

Enter← ﬂoat64 の行列 a2f を作成>>> t1 = time.time()>>> a3f = np.dot(a1f,a2f)>>> t2 = time.time()>>> print(t2-t1)

←開始時間

Enter

←行列の積の計算

Enter

←終了時間

Enter

←経過時間

Enter

←単位は秒

0.06248879432678223

例．object の場合の計算時間（先の例の続き）>>> a1oi = a1i.astype(’object’)Enter← object の行列 a1oi を作成>>> a2oi = a2i.astype(’object’)Enter← object の行列 a2oi を作成>>> t1 = time.time()

←開始時間

Enter

>>> t2 = time.time()>>> print(t2-t1)
7.531817436218262

←終了時間

Enter

Enter

←行列の積の計算

Enter>>> a3oi = np.dot(a1oi,a2oi)

←経過時間

←単位は秒

これは CPU Intel Core i7-6770HQ 2.59GHz，RAM 16GB，OS Windows 10 Pro，NumPy with Intel MKL の環境下での実行結果である．上記の時間計測を 3 回実行して計算時間の平均を求めたものを表 25 に示す．

型

表 25: 型毎に異なる計算時間
平均計算時間（秒） int64 の場合に対する比率

int64

0.165572

1

ﬂoat640.059437

0.358981

object

7.665909

46.299683

上に示した計算機環境では ﬂoat64 型の場合の計算が最も早いことがわかる．また，object 型の場合では計算速度が非常に小さくなることもわかる．

3.1.26

画像データの扱い

NumPy では画素の RGB 値の配列（図 82 参照）を画像として表示することができる．
画素の配列は全体としては 3 次元の構造である．このようなデータを画像として表示する方法について，例を示しながら説明する．
図 83 のような画像を構成する画素の配列を作成することを考える．

138

図 82: NumPy における画素の配列

図 83: サンプル：3 色の画像
この画像を構成する画素の配列は [赤, 赤,…, 緑, 緑,…, 青, 青,…] の行を多数束ねた配列であると見ることができる．すなわち，[ [赤, 赤,…, 緑, 緑,…, 青, 青,…][赤, 赤,…, 緑, 緑,…, 青, 青,…][赤, 赤,…, 緑, 緑,…, 青, 青,…]]：のような配列を作成することになる．
（次の例）
例．図 83 を画素の配列として作成する>>> import numpy as np← NumPy の読込みEnter>>> r = [[255,0,0,255]]*100Enter←赤の画素の配列>>> g = [[0,255,0,255]]*100Enter←緑の画素の配列>>> b = [[0,0,255,255]]*100Enter←青の画素の配列

Enter>>> imA = np.array([r+g+b]*200)←上記 3 つを連結してそれを 200 行分作成

これで imA に画素の配列ができた．次にこれを matplotlib によって可視化する．
（次の例）
例．作成した配列を画像として表示する．
（先の例の続き）>>> import matplotlib.pyplot as plt>>> plt.figure()Enter←描画処理の開始<Figure size 640x480 with 0 Axes>>>> plt.imshow( imA )← matplotlib の読込み

Enter

Enter

←戻り値

←画素の配列を表示するメソッド<matplotlib.image.AxesImage object at 0x0000022B5C136208>>>> plt.show()

Enter←描画の実行

この結果，imshow メソッドによって図 84 のように表示される．

139

←戻り値

図 84: 画素の配列を表示した例

3.1.26.1画素の配列から画像データへの変換（PIL ライブラリとの連携）

Pillow ライブラリ（p.20）を用いると NumPy で作成した画素の配列を画像データに変換することができる．
例．NumPy の画素配列を Pillow の Image オブジェクトに変換する（先の例の続き）>>> from PIL import Image← Pillow ライブラリから Image クラスを読み込む

Enter>>> im = Image.fromarray( np.uint8(imA) ) Enter ←画素配列を Pillow の Image オブジェクトに変換>>> im.show()

Enter

←表示処理

Enter

>>> im.save(’rgb01.png’)←画像をファイルに保存処理の手順としては，NumPy の画素配列を 8 ビット符号無し整数の配列に変換（uint8 メソッド）し，それを Pillow の

fromarray メソッドによって Image オブジェクトに変換する．この例では，出来上がった Image オブジェクトを Image
クラスの show メソッドでディスプレイに表示している．
（画像ビューワが開いて図 83 のような画像が表示される）

3.1.26.2

画像データから画素の配列への変換（PIL ライブラリとの連携）

NumPy の asarray メソッドを使用すると，Pillow の Image オブジェクトを NumPy の画素配列に変換することができる．
（次の例参照）
例．Image オブジェクトを画素配列に変換（先の例の続き）>>> imA2 = np.asarray(im)>>> plt.figure()Enter← Image オブジェクトを画素配列に変換

Enter←描画処理の開始←戻り値<Figure size 640x480 with 0 Axes>>>> plt.imshow( imA2 )Enter←画素の配列を表示<matplotlib.image.AxesImage object at 0x0000022B5AF479B0>>>> plt.show()

Enter

←戻り値

←描画の実行

この結果，図 84 のように表示される．

課題）図 85 のような画像を，画素配列として作成して matplotlib の imshow メソッドで表示せよ．

図 85: 作成する画像

Image オブジェクトをファイルに保存する方法など，Pillow に関することは「1.2 Pillow」（p.20）を参照のこと．

140

3.1.26.3

OpenCV における画素の配列

OpenCV ライブラリ39 による画像の扱いでは，画素の RGB 成分の並びが異なるので注意が必要である．OpenCV
では，例えば次のようにして画像ファイルを読み込むことができる．
例．OpenCV ライブラリの imread メソッドによる画像の読込み（先の例の続き）>>> import cv2

Enter← OpenCV ライブラリの読込み>>> imcv = cv2.imread( ’rgb01.png’, cv2.IMREAD UNCHANGED ) Enter ←画像ファイルの読込み>>> type( imcv )←データ型を調べる

Enter← NumPy の配列である<class ’numpy.ndarray’>←配列の形状を調べる>>> imcv.shapeEnter(200, 300, 4)←配列の形状

これは，先の例で作成した画像ファイル ’rgb01.png’ を読み込む例であるが，このように imread メソッドで画像ファイ
ルを読み込むと，直接 NumPy の配列（ndarray）の形で画素が得られる．ただし，画素の色の成分の並びが B,G,R,α（青，緑，赤，α）の順であるので，次のようにして表示すると，元の表示（図 84）と異なる結果となる．
例．得られた画素の配列を表示する（先の例の続き）>>> plt.imshow( imcv )Enter←画像を表示<matplotlib.image.AxesImage object at 0x000001788527D708>>>> plt.show()Enter←作図の実行

この結果，図 86 のように表示されてしまう．

図 86: OpenCV の imread メソッドで読み込んだ配列を表示
上の例で得られた画素配列 imcv の色成分の順序を R,G,B, α にするには，例えば次のような変換処理を行う．
例．色成分の並びの変更（先の例の続き）>>> imcv2 = imcv[:,:,[2,1,0,3]]

Enter

←変換処理

こうすることで，imcv の画素の縦と横の並び順はそのままで，画素の色成分の部分の値の並びを変更することができる．
（変換結果を imcv2 に得ている）
この処理で得られた imcv2 を表示する例を次に示す．
例．色成分の順序を修正した画像を表示（先の例の続き）

Enter←修正した画像を表示>>> plt.imshow( imcv2 )<matplotlib.image.AxesImage object at 0x0000017885688F88>>>> plt.show()Enter←作図の実行

この結果，図 87 のように表示される．

39 p.1「1.1 OpenCV」で解説している．

141

図 87: 色成分の順序を修正した画像

3.1.26.4

サンプルプログラム：画像の三色分解

PIL ライブラリ経由で読み取った画像を 3 つの原色（RGB）に分解して，それぞれ表示するプログラム imshow01.py
を示す．
プログラム：imshow01.py
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

# coding : utf -8# ライブラリの読込み
import numpy as np
import matplotlib . pyplot as plt
from PIL import Image# Image from https :// pixabay . com / ja /IM = Image . open ( ’ ImgCat . jpg ’)# 読込み(R ,G , B ) = IM . split ()# 3色 分 解# 配列データに変換
im = np . asarray ( IM )r = np . asarray ( R )g = np . asarray ( G )b = np . asarray ( B )# 表示( fig , axs ) = plt . subplots (1 ,2 , figsize =(8 ,2))axs [0]. imshow ( im );axs [0]. set_title ( ’ Original ’)axs [1]. imshow (r , cmap = ’ Greys_r ’);axs [1]. set_title ( ’ Grayscale ’)# plt . savefig ( ’ imshow01_exe1 . eps ’)plt . show ()( fig , axs ) = plt . subplots (1 ,3 , figsize =(12 ,2))axs [0]. imshow (r , cmap = ’ Reds_r ’);axs [0]. set_title ( ’ Red ’)axs [1]. imshow (r , cmap = ’ Greens_r ’);axs [1]. set_title ( ’ Green ’)axs [2]. imshow (r , cmap = ’ Blues_r ’);axs [2]. set_title ( ’ Blue ’)# plt . savefig ( ’ imshow01_exe2 . eps ’)plt . show ()解説：

PIL の Image オブジェクトに対して split メソッドを実行（9 行目）すると 3 色（RGB）に分解された 3 つの Image
オブジェクトが返される．それらを配列に変換（11〜14 行目）し，imshow で表示している．
このプログラムを実行すると図 88 のように表示される．

142

図 88: グレースケール表示と 3 色分解した画像の表示

143

3.1.27

図形の描画：matplotlib.patches

matplotlib.patches は各種の幾何学図形を表示する機能を提供する．ここでは，matplotlib.patches の描画機能の内の一部40 について解説する．
ここで解説する描画機能は matplotlib によるものであり，使用に際して下記のように matplotlib.pyplot と mat-

plotlib.patches を読み込む必要がある．
import matplotlib.pyplot as plt
import matplotlib.patches as pat
これにより，幾何学図形の API を接頭辞「pat.」をつけて呼び出すことができる．
図形描画の手順：

matplotlib.patches の各種図形クラスのオブジェクトを作成し，それを AxesSubplot （p.85）に対して add patch
メソッドで描画する．

3.1.27.1

四角形，円，楕円，正多角形■ 四角形：

Rectangle( xy=四角形の左下の座標, width=横幅, height=高さ,
fc=塗りの色, ec=線の色, lw=線の太さ, angle=回転の角度 )キーワード引数「angle=」には四角形の傾き（反時計回りの回転の角度）を 360 進法の度で与える．この場合の回転の中心は，四角形の左下の座標である．
■ 円：
■ 楕円：

Circle( xy=中心の座標, radius=半径, fc=塗りの色, ec=線の色, lw=線の太さ ) indexCircle
Ellipse( xy=中心の座標, width=横幅, height=高さ,
fc=塗りの色, ec=線の色, lw=線の太さ, angle=回転の角度 )width 以降の引数については四角形の場合に準ずる．
■ 正多角形：

RegularPolygon( xy=中心の座標, radius=半径, numVertices=頂点の数,
fc=塗りの色, ec=線の色, lw=線の太さ, orientation=回転の角度 )キーワード引数「orientation=」には多角形の傾き（反時計回りの回転の角度）を与えるが，この場合は弧度法（ラジアン）の値で与えることに注意しなければならない．それ以外の引数については円の場合に準ずる．
これらの図形を表示するサンプルプログラム mPolygon2D01.py を示す．
プログラム：mPolygon2D01.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19

# coding : utf -8
import numpy as np
import matplotlib . pyplot as plt
import matplotlib . patches as pat# 四角形
p1 = pat . Rectangle ( xy =(0 ,0) , width =1.5 , height =1 , fc = ’ blue ’ , ec = ’ red ’ , lw =4 )p2 = pat . Rectangle ( xy =(0 ,1) , width =1.5 , height =1 , fc = ’ blue ’ , ec = ’ red ’ , lw =4 ,angle =30 )# 円
p3 = pat . Circle ( xy =(2.2 ,0.5) , radius =0.5 , fc = ’ yellow ’ , ec = ’ blue ’ , lw =8 )# 楕円
p4 = pat . Ellipse ( xy =(3.7 ,0.5) , width =1.5 , height =1 ,fc = ’ cyan ’ , ec = ’ magenta ’ , lw =6 )p5 = pat . Ellipse ( xy =(3.7 ,1.8) , width =1.5 , height =1 ,fc = ’ cyan ’ , ec = ’ magenta ’ , lw =6 , angle =30 )40 詳しくは matplotlib の公式インターネットサイト（https://matplotlib.org/）を参照のこと．

144

20
21
22
23
24
25
26
27
28
29
30
31
32

# 正多角形
p6 = pat . RegularPolygon ( xy =(5.2 ,0.5) , radius =0.5 , numVertices =5 ,fc = ’ magenta ’ , ec = ’ green ’ , lw =8 )p7 = pat . RegularPolygon ( xy =(5.2 ,1.8) , radius =0.5 , numVertices =5 ,fc = ’ magenta ’ , ec = ’ green ’ , lw =8 , ori entation = np . pi /2 )# 描画
plt . figure ( figsize =(8 ,3.53) )ax = plt . gca ()ax . add_patch ( p1 );ax . add_patch ( p2 );ax . add_patch ( p5 );ax . add_patch ( p6 );plt . xlim ( -0.8 ,6.0); plt . ylim ( -0.2 ,2.8)
plt . show ()ax . add_patch ( p3 );ax . add_patch ( p7 )ax . add_patch ( p4 )このプログラムを実行すると図 89 のように表示される．

図 89: mPolygon2D01.py の実行結果

3.1.27.2

円弧（楕円弧）円弧は Arc オブジェクトとして描画する．

Arc( xy=中心の座標, width=横幅, height=高さ, ec=線の色, lw=線の太さ,
theta1=開始の角度, theta2=終了の角度, angle=回転の角度 )「開始の角度」で始まり「終了の角度」で終わる円弧（楕円弧）を作成する．それ以外の引数については楕円の場
合に準ずる．角度は反時計回り，360 進法の度で与える．

Arc を使用したサンプルプログラム mPolygon2D02.py を示す．
プログラム：mPolygon2D02.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21

# coding : utf -8
import matplotlib . pyplot as plt
import matplotlib . patches as pat# 円弧
p1 = pat . Arc ( xy =(0 ,0.5) , width =0.8 , height =0.8 ,
ec = ’ red ’ , lw =12 , theta1 =30 , theta2 =330 )p2 = pat . Arc ( xy =(0.3 ,0.5) , width =0.8 , height =0.8 ,
ec = ’ red ’ , lw =12 , theta1 =330 , theta2 =30 )p3 = pat . Arc ( xy =(2 ,0.5) , width =1.8 , height =0.8 ,
ec = ’ blue ’ , lw =12 , theta1 =290 , theta2 =250 )p4 = pat . Arc ( xy =(4 ,0.5) , width =1.8 , height =0.8 ,
ec = ’ blue ’ , lw =12 , theta1 =290 , theta2 =250 , angle =30 )# 描画
plt . figure ( figsize =(14 ,3.2) )ax = plt . gca ()ax . add_patch ( p1 );ax . add_patch ( p2 )ax . add_patch ( p3 );ax . add_patch ( p4 )plt . xlim ( -0.8 ,5.2); plt . ylim ( -0.2 ,1.3)
plt . show ()145

このプログラムを実行すると図 90 のように 4 つの円弧が表示される．

図 90: mPolygon2D02.py の実行結果

3.1.27.3

ポリゴン

与えられた複数の座標を結ぶポリゴンは Polygon オブジェクトとして作成する．

Polygon( xy=座標のリスト, fc=塗りの色, ec=線の色, lw=線の太さ )キーワード引数「fc=」以降の引数については四角形の場合に準ずる．

Polygon を使用したサンプルプログラム mPolygon2D03.py を示す．
プログラム：mPolygon2D03.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14

# coding : utf -8
import matplotlib . pyplot as plt
import matplotlib . patches as pat# 円弧# ポリゴン
p1 = pat . Polygon ( xy =[(0 ,0) ,(1 ,0) ,(0 ,1)] , fc = ’ yellow ’ , ec = ’ green ’ , lw =8 )# 描画
plt . figure ( figsize =(4 ,4) )ax = plt . gca ()ax . add_patch ( p1 )plt . xlim ( -0.2 ,1.2); plt . ylim ( -0.2 ,1.2)
plt . show ()このプログラムを実行すると図 91 のようなポリゴンが表示される．

図 91: mPolygon2D03.py の実行結果

3.1.283 次元のポリゴン表示

先の「3.1.17 データの可視化：3 次元プロット」（p.110）で解説した 3 次元プロット空間にポリゴンを表示する最も簡単な方法41 について説明する．
41 詳しくは matplotlib の公式インターネットサイト（https://matplotlib.org/）を参照のこと．

146

3 次元のポリゴンオブジェクトは mpl toolkits.mplot3d.art3d が提供する Poly3DCollection オブジェクトであり，これを 3 次元空間に表示するためには次のようにして必要なライブラリを読み込んでおく．

import matplotlib.pyplot as plt
import matplotlib.patches as patfrom mpl toolkits.mplot3d import Axes3D
import mpl toolkits.mplot3d.art3d as art3d■ 3 次元ポリゴン：

Poly3DCollection( 3 次元座標リスト, color=色 )作成した Poly3DCollection オブジェクトは 3 次元プロット空間（Axes3D）に対して add collection3d メソッドを使用することで表示する．

Poly3DCollection を使用したサンプルプログラム mPolygon3D00.py を示す．
プログラム：mPolygon3D00.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19

# coding : utf -8
import matplotlib . pyplot as plt
import matplotlib . patches as patfrom mpl_toolkits . mplot3d import Axes3D
import mpl_toolkits . mplot3d . art3d as art3d# ポリゴン
p1 = art3d . Poly3DCollection ([(0 ,0 ,0) ,(0 ,2 ,0) ,(1 ,1 ,0)] , color = ’ red ’ )p2 = art3d . Poly3DCollection ([(0 ,0 ,0) ,(1 ,1 ,1) ,(1 ,1 ,0)] , color = ’ green ’ )p3 = art3d . Poly3DCollection ([(0 ,2 ,0) ,(1 ,1 ,1) ,(1 ,1 ,0)] , color = ’ blue ’ )p4 = art3d . Poly3DCollection ([(0 ,0 ,0) ,(1 ,1 ,1) ,(0 ,2 ,0)] , color = ’ yellow ’ )# 描画
ax = Axes3D ( plt . figure ())
ax . add_collection3d ( p1 );ax . add_collection3d ( p2 )ax . add_collection3d ( p3 );ax . add_collection3d ( p4 )ax . set_xlim ( -0.2 ,1.2); ax . set_ylim ( -0.2 ,2.5); ax . set_zlim ( -0.2 ,1.0)
ax . set_xlabel ( ’x ’); ax . set_ylabel ( ’y ’); ax . set_zlabel ( ’z ’)
plt . show ()このプログラムを実行すると図 92 のようなポリゴンが表示される．

図 92: mPolygon3D00.py の実行結果（同一のグラフを様々な角度で表示した例）
この方法では add collection3d メソッドで追加した順序でポリゴンが重なり合う．従って隠線処理が正しく施されない（図 93）ことに注意すること．

図 93: 不自然なポリゴンの配置の例

147

3.1.29

日付，時刻の扱い

3.1.29.1

datetime64 クラス

NumPy は日付と時刻を表現するための datetime64 クラスを提供する．このクラスのインスタンスは 1 つのタイム
スタンプを表す．ISO8601 形式の日付，時刻をコンストラクタに与えて datetime64 オブジェクトを生成する例を次に示す．
例．2022 年 1 月 1 日 00:00:00 を表す datetime64 オブジェクトの作成← NumPy の読込みEnter>>> import numpy as np>>> d1 = np.datetime64(’2022-01-01T00:00:00’)>>> d1Enter← datetime64 オブジェクトの生成

←確認

Enter

←作成されたオブジェクト

numpy.datetime64(’2022-01-01T00:00:00’)
注意）

NumPy 1.11.0 以降の datetime64 ではタイムゾーン情報を扱わないとしている．ただし，古い版の NumPy との互換性を保つために当面はタイムゾーン情報が扱えるが，将来においてタイムゾーン情報を扱う機能が廃止される可能性があるため，タイムゾーンは指定せずに（UTC の解釈で）datetime64 を扱うこと．
コンストラクタに与える日付，時刻の文字列は省略した形で記述することが可能である．その場合は，その記述が示す日付時刻の開始時点のタイムスタンプと同じものとなる．
（次の例）
例．省略した記述を与えて作成した datetime64 オブジェクト（先の例の続き）>>> np.datetime64(’2022-01-01’) == d1←時刻を省略したもの

Enter←先の d1 と同じ

True←「日」以降を省略したものEnter>>> np.datetime64(’2022-01’) == d1←先の d1 と同じ

True

Enter

>>> np.datetime64(’2022’) == d1←「月」以降を省略したもの←先の d1 と同じ

True

コンストラクタに整数値を与えて datetime64 オブジェクトを作成することができる．
書き方：

datetime64( 整数値, 単位 )

この形を取る場合，’1970-01-01T00:00:00’ を基準とした datetime64 オブジェクトが作成される．またその際「整数値」が意味するものは「単位」（文字列）で指定した経過時間となる．
例．’1970-01-01T00:00:00’ と基準とした datetime64 オブジェクトの作成>>> np.datetime64(1,’Y’)Enter←’1971-01-01T00:00:00’ となる

numpy.datetime64(’1971’)>>> np.datetime64(-1,’s’)← 1 年後Enter← 1 秒前numpy.datetime64(’1969-12-31T23:59:59’)
この例では「1 年後」と「1 秒前」の日付を作成しているが「単位」の部分に指定できるものを表 26 に示す．

3.1.29.2単位

意味

表 26: 時間の単位（一部）
単位 意味
単位 意味

’Y’

年

’M’

月

’W’

’h’

時

’m’

分

’s’

’us’

マイクロ秒

’ns’

ナノ秒

単位

意味

週

’D’

日

秒

’ms’

ミリ秒

timedelta64 クラス

datetime64 オブエジェクトの差を通常の減算演算子「-」で求めることができる．
（次の例）

148

例．datetime64 オブジェクトの差（その 1）>>> d1 = np.datetime64(’2022-01-01’)

Enter← 1 つ目>>> d2 = np.datetime64(’2023-01-01’)

Enter← 2 つ目>>> td = d2 - d1>>> td←それらの差

Enter

←確認

Enter

←結果（365 日）

numpy.timedelta64(365,’D’)

この例では，ちょうど 1 年の差がある datetime64 オブジェクトの減算を実行したものである．減算の結果は timedelta64
クラスのオブジェクトとして得られる．このクラスのオブジェクトは

timedelta64( 値, 単位 )の形式で時間の長さを表す．この例では「365 日の差」を表すものが得られている．減算に使用する datetime64 オブ
ジェクトによって減算の結果の単位が異なるものとなる．
（次の例）
例．datetime64 オブジェクトの差（その 2）>>> d1 = np.datetime64(’2022-01-01T00:00:00’)

Enter← 1 つ目>>> d2 = np.datetime64(’2023-01-01T00:00:00’)

Enter← 2 つ目>>> td = d2 - d1>>> td←それらの差

Enter

←確認

Enter

numpy.timedelta64(31536000,’s’)←結果（365 日の秒数）

この例は先の例と同様の処理を実行したものであるが，減算に使用した datetime64 オブジェクトが秒単位であることから，減算結果の timedelta64 オブジェクトも秒単位になっている．
■ グレゴリオ暦

datetime64，timedelta64 はグレゴリオ暦を反映している．以下に閏年が関わる処理の例を示す．
例．2020 年（閏年）と 2021 年の差>>> d1 = np.datetime64(’2020’)

Enter

←閏年

>>> d2 = np.datetime64(’2021’)

Enter

←平年

>>> d2 - d1Enternumpy.timedelta64(1,’Y’)←差を取ると…
← 1 年の差

これは「年」を単位として差を算出したものであり，結果は「1 年」であることがわかる．更に「日」を単位として差を算出すると次のようになる．
例．「日」を単位とした時間の長さ>>> np.datetime64(’2021-01-01’) - np.datetime64(’2020-01-01’)
numpy.timedelta64(366,’D’)←閏年の 1 年

Enter←平年の 1 年← 366 日>>> np.datetime64(’2022-01-01’) - np.datetime64(’2021-01-01’)
numpy.timedelta64(365,’D’)Enter← 365 日時間の長さについて考える際は，単位と暦を意識する必要がある．

3.1.29.3

日付，時刻の応用例

datetime64，timedelta64 オブジェクトを要素として持つ配列を作成する例を示す．

149

例．15 分おきの datetime64 の配列>>> t1 = np.datetime64(’2022-01-01T00:00’)

Enter←自（分単位）>>> t2 = np.datetime64(’2022-01-01T01:00’)

Enter←至（分単位）>>> a12 = np.arange(t1,t2,np.timedelta64(15,’m’))>>> a12Enter← 15 分おきの配列作成

←確認

Enter

array([’2022-01-01T00:00’, ’2022-01-01T00:15’, ’2022-01-01T00:30’,’2022-01-01T00:45’], dtype=’datetime64[m]’)←得られた配列（分単位）例．10 マイクロ秒おきの datetime64 の配列（先の例の続き）>>> t3 = np.datetime64(’2022-01-01T00:00:00’)

Enter>>> t4 = np.datetime64(’2022-01-01T00:00:00.000040’)>>> a34 = np.arange(t3,t4,np.timedelta64(10,’us’))>>> a34←自（秒単位）

Enter
Enter

←至（マイクロ秒単位）← 10 マイクロ秒おきの配列作成

←確認

Enter

array([’2022-01-01T00:00:00.000000’, ’2022-01-01T00:00:00.000010’,’2022-01-01T00:00:00.000020’, ’2022-01-01T00:00:00.000030’],
dtype=’datetime64[us]’)←得られた配列（マイクロ秒単位）
例．上の例で得られた配列 a12，a34 の 1 階差分の配列（先の例の続き）>>> np.diff(a12)Enter← a12 の 1 階差分

array([15, 15, 15], dtype=’timedelta64[m]’)>>> np.diff(a34)Enter←分単位の timedelta64 オブジェクトの配列← a34 の 1 階差分

array([10, 10, 10], dtype=’timedelta64[us]’)150←マイクロ秒単位の timedelta64 オブジェクトの配列

その他の機能

3.1.303.1.30.1

基準以上／以下のデータの抽出ある基準と比較して，それより大きい／小さいデータを抽出する関数に maximum ，minimum がある．
書き方：

maximum( データ配列, 基準値の配列 )書き方：

minimum( データ配列, 基準値の配列 )maximum 関数は「基準値の配列」以上のものを「データ配列」から抽出して返す．このとき，データ列の要素の内で基準値未満の要素に関しては，対応する基準値で置き換えたものを戻り値の要素とする．同様に，minimum 関
数は「基準値の配列」以下のものを「データ配列」から抽出する．このとき，データ配列の要素の内で基準値より大きい要素に関しては，対応する基準値の要素で置き換えたものを戻り値の要素とする．
「データ配列」と「基準値の配列」の長さは同じものであるとする．
これら関数を使用するサンプルプログラム maximum minimum01.py を示す．
プログラム：maximum minimum01.py
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

# coding : utf -8# ライブラリの読込み
import numpy as np
import matplotlib . pyplot as plt#xyr

データの作成= np . linspace (0 ,20 ,1000)= np . sin ( x ) / 2.0= np . random . rand (1000)*2 - 1# 基準列# データ列# データとベースラインのプロット
plt . figure ( figsize =(4 ,4))plt . plot (x ,r , label = ’ data ’ , ls = ’ None ’ , marker = ’. ’)
plt . plot (x ,y , label = ’ base line ’ , lw =2.5 , c = ’ red ’)plt . ylim ( -1.1 ,1.1)
plt . legend ()plt . title ( ’ Data and baseline ’)plt . show ()# maximumによる抽出
r1 = np . maximum (r , y )# 基準列以上のデータを取り出す
plt . figure ( figsize =(4 ,4))plt . plot (x , r1 , ls = ’ None ’ , marker = ’. ’)
plt . ylim ( -1.1 ,1.1)
plt . title ( ’ Upper side ’)plt . show ()# minimumによる抽出
r2 = np . minimum (r , y )# 基準列以下のデータを取り出す
plt . figure ( figsize =(4 ,4))plt . plot (x , r2 , ls = ’ None ’ , marker = ’. ’)
plt . ylim ( -1.1 ,1.1)
plt . title ( ’ Lower side ’)plt . show ()このプログラムは，データ配列 r を基準値の配列 y と比較して抽出する例である．7〜18 行目でデータ配列と基準値の配列を生成して，それらをプロット（図 94 の a）している．21〜26 行目で基準値以上のデータ（図 94 の b）を，29〜34 行目で基準値以下のデータ（図 94 の c）を抽出してプロットしている．

maximum，minimum 関数の第 2 引数（基準値）にスカラー値を与えることもできる．サンプルプログラム maximum minimum02.py でそれを示す．
プログラム：maximum minimum02.py
12
3
4# coding : utf -8# ライブラリの読込み
import numpy as np
import matplotlib . pyplot as plt

151

(a) データ配列と基準値の配列(b) 基準値以上のデータ(c) 基準値以下のデータ

図 94: 上側，下側のデータの抽出
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

# データの作成
x = np . linspace (0 ,20 ,1000)y = np . sin ( x )# 元のデータのプロット
plt . figure ( figsize =(4 ,4))plt . plot (x ,y , lw =2.5 , c = ’ red ’)plt . ylim ( -1.1 ,1.1)
plt . title ( ’ Original ’)plt . show ()# スカラーによる抽出（上側）y1 = np . maximum (y ,0.5)
plt . figure ( figsize =(4 ,4))plt . plot (x , y1 , label = ’ base line ’ , lw =2.5 , c = ’ red ’)plt . ylim ( -1.1 ,1.1)
plt . title ( ’ Upper side ’)plt . show ()# スカラーによる抽出（下側）
y1 = np . minimum (y ,0.5)
plt . figure ( figsize =(4 ,4))plt . plot (x , y1 , label = ’ base line ’ , lw =2.5 , c = ’ red ’)plt . ylim ( -1.1 ,1.1)
plt . title ( ’ Lower side ’)plt . show ()このプログラムを実行すると，図 95 のようなグラフが順番に表示される．

(a) 元のデータ列(b) 基準値以上のデータ

図 95: スカラー値を基準にして上側，下側データを抽出
このように，スカラーの基準値を与えると単純な切り取りができる．

152(c) 基準値以下のデータ

3.1.30.2

指定した範囲のデータの抽出

clip 関数を用いることで配列の要素の値を指定した範囲内に制限することができる．
書き方：

clip( 配列, 最小値, 最大値 )「配列」の要素の内，「最小値」よりも小さいものを「最小値」に，「最大値」よりも大きいものを「最大値」に置き換える．次に示すサンプルプログラム npclip01.py は，y = sin(x) を −0.5 ≤ y ≤ 0.5 の範囲に制限してプロットするものである．
プログラム：npclip01.py
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

# coding : utf -8# ライブラリの読込み
import numpy as np
import matplotlib . pyplot as plt# データの生成
x = np . linspace (0 ,30 ,200)
y = np . sin ( x )# プ ロ ッ ト ： clipなし
plt . figure ( figsize =(6 ,4))plt . plot ( x , y )plt . xlabel ( ’x ’);plt . ylabel ( ’y ’)
plt . ylim ( -1.1 ,1.1)
plt . title ( ’ y = sin ( x ) ’)plt . show ()print ( ’ min : ’ , y . min () , ’ max : ’ , y . max ())# プ ロ ッ ト ： clipあり
yc = np . clip ( y , -0.5 , 0.5 )plt . figure ( figsize =(6 ,4))plt . plot ( x , yc )plt . xlabel ( ’x ’);plt . ylabel ( ’ yc ’)plt . ylim ( -1.1 ,1.1)
plt . title ( ’ clipped : yc = np . clip (y , -0.5 ,0.5) ’)plt . show ()print ( ’ min : ’ , yc . min () , ’ max : ’ , yc . max ())

このプログラムを実行すると，図 96 のようなグラフが順番に表示される．

(a) 制限なし(b) clip で -0.5〜0.5 の範囲に制限

図 96: clip 関数による値の制限

y の値を −0.5 ≤ y ≤ 0.5 の範囲に制限している様子がわかる．
clip 関数の第 2, 第 3 引数（最小値，最大値）に範囲を表すデータ列を与えることもできる．そのことを次のサンプ
ルプログラム npclip02.py で示す．
プログラム：npclip02.py
1# coding : utf -8

153

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

# ライブラリの読込み
import numpy as np
import matplotlib . pyplot as plt# データの作成
x = np . linspace (0 ,20 ,1000)
y1 = np . sin ( x ) / 4.0 + 0.75
y2 = np . sin ( x ) / 4.0 - 0.75
r = np . random . rand (1000)*2 - 1

# 上限
# 下限
# データ列# データ，下限，上限のプロット
plt . figure ( figsize =(6 ,4))plt . plot (x ,r , label = ’ data ’ , ls = ’ None ’ , marker = ’. ’)
plt . plot (x , y1 , label = ’ upper bound ’ , lw =2)
plt . plot (x , y2 , label = ’ lower bound ’ , lw =2)
plt . ylim ( -1.1 ,1.1)
plt . legend ()plt . title ( ’ Data and bounds ’)plt . show ()# プ ロ ッ ト ： clipによる制限
rc = np . clip ( r , y2 , y1 )plt . figure ( figsize =(6 ,4))plt . plot ( x , rc , ls = ’ None ’ , marker = ’. ’ )plt . ylim ( -1.1 ,1.1)
plt . title ( ’ clipped data ’)plt . show ()このプログラムを実行すると，図 97 のようなグラフが順番に表示される．

(a) データ列，下限，上限(b) clip 関数で制限した結果

図 97: 下限，上限の列を clip 関数に与える例
指定した下限，上限の範囲にデータが制限されている様子がわかる．

154

科学技術計算用ライブラリ： SciPy

3.2

Scipy は NumPy を基礎にして構築されたライブラリであり，科学，工学のための高度な数値計算のための機能（表27）を提供する．SciPy 本体と関連情報は公式インターネットサイト https://www.scipy.org/ から得られる．
表 27: SciPy に含まれるパッケージ
パッケージ

説明

パッケージ

説明

constants
ﬀtpackinterpolate
linalgndimagesignalspatialstats

物理定数と変換係数
離散フーリエ変換
データの補間線形代数
多次元の画像処理
信号処理ツール
KD 木，最近傍，距離関数
統計関連の機能

cluster
integrateio
misc
optimizesparsespecial

階層的クラスタリング，ベクトル量子化
数値積分
データ入出力ユーティリティ系
線形計画法を含む最適化計算
スパース行列の取り扱い
その他の特別な機能

本書では SciPy の機能の一部を抜粋して説明する．本書で触れない事柄に関しては SciPy の公式インターネットサ
イトなどの情報を参照のこと．

3.2.1

信号処理ツール: scipy.signal

3.2.1.1

基本的な波形の生成■ 矩形波（方形波）： square 関数
書き方：square( 時間軸の配列, duty=パルス幅 )「時間軸の配列」に対する矩形波の波形（周期は 2π ）を生成し，それを配列として返す．戻り値の範囲は -1.0〜1.0である．
「パルス幅」には 0〜1.0 の値を指定する．パルス幅の暗黙値は 0.5 である．
次の例は，時間軸 t = 0〜1 に対する周波数 f = 1 Hz の矩形波 square(2πf t) を生成して波形をプロットするもの
である．
例．周期 1 つ分の矩形波>>> import numpy as np←プロット用ライブラリの読込み

Enter>>> import matplotlib.pyplot as plt← NumPy の読込みEnter>>> from scipy import signal

Enter← scipy.signal の読込み>>> t = np.linspace(0,1,200)Enter←時間軸の生成>>> f = 1Enter

←周波数（1Hz）の設定>>> y = signal.square(2*np.pi*f*t)

Enter←矩形波の生成>>> f = plt.figure(figsize=(5,2))

Enter←作図の開始>>> r1 = plt.plot(t,y)>>> r2 = plt.xlabel(’t’)>>> plt.show()

Enter

Enter

←波形のプロットEnter←グラフの横軸ラベル←作図の実行

この実行結果として図 98 の (a) が表示される．周波数を f=5 として実行すると同図の (b) が表示される．

(a) f = 1 の場合の波形(b) f = 5 の場合の波形

図 98: 矩形波の生成
次の例は，キーワード引数 ‘duty=’ の値（パルス幅の比率）を 0.2 として実行するものである．

155

例．duty=0.2 として実行した例（先の例の続き）←周波数（1Hz）の設定

Enter>>> f = 1>>> r1 = plt.plot(t,y)>>> r2 = plt.xlabel(’t’)←波形のプロット←グラフの横軸ラベル

Enter←作図の実行Enter>>> plt.show()Enter←作図の開始Enter>>> f = plt.figure(figsize=(5,2))←矩形波の生成Enter>>> y = signal.square(2*np.pi*f*t,duty=0.2)

この実行結果として図 99 の (a) が表示される．

(a) duty=0.2 の場合の波形(b) パルス幅を連続的に変化させた場合の波形

図 99: 矩形波の生成
パルス幅は連続的に変化させること（パルス幅変調，PWM：pulse width modulation）ができる．そのためには，
時間軸配列の各要素に対応するパルス幅の値を配列にしてキーワード引数 ‘duty=’ に与える．
次の例は，正弦波 (sin(2πt) + 1)/2 でパルス幅を変調する例である．
例．パルス幅を連続的に変化させる例（先の例の続き）>>> m = (np.sin(2*np.pi*t)+1)/2>>> f = 30

←変調用の正弦波 (sin(2πt) + 1)/2 の配列

Enter←周波数（30Hz）の設定

Enter

Enter

>>> y = signal.square(2*np.pi*f*t,duty=m)>>> f = plt.figure(figsize=(5,2))←矩形波の生成←作図の開始Enter>>> r1 = plt.plot(t,m)

Enter←変調用正弦波のプロット>>> r2 = plt.plot(t,y)

Enter← PWM の結果の波形のプロット>>> r3 = plt.xlabel(’t’)>>> plt.show()

Enter

Enter

←グラフの横軸ラベル←作図の実行

この実行結果として図 99 の (b) が表示される．このグラフには，変調用の正弦波 (sin(2πt) + 1)/2 と変調された矩形波が重ねて表示される．
■ 鋸歯状波（ノコギリ波）： sawtooth 関数
書き方：

sawtooth( 時間軸の配列, width=立ち上がり幅 )「時間軸の配列」に対する鋸歯状波の波形（周期は 2π ）を生成し，それを配列として返す．戻り値の範囲は -1.0〜

1.0 である．
「立ち上がり幅」には 0〜1.0 の値を指定する．width の暗黙値は 0.5 である．
次の例は，時間軸 t = 0〜1 に対する周波数 f = 1 Hz の鋸歯状波 sawtooth(2πf t) を生成して波形をプロットするものである．
例．周期 1 つ分の鋸歯状波（先の例の続き）>>> f = 1Enter

←周波数（1Hz）の設定>>> y = signal.sawtooth(2*np.pi*f*t)>>> f = plt.figure(figsize=(5,2))>>> r1 = plt.plot(t,y)>>> r2 = plt.xlabel(’t’)>>> plt.show()

Enter

Enter
Enter

←鋸歯状波の生成

Enter

Enter

←作図の開始←波形のプロット←グラフの横軸ラベル←作図の実行

この実行結果として図 100 の (a) が表示される．

156

(a) 鋸歯状波の波形(b) 立ち上がり幅を 0.5 にした場合の波形

図 100: 鋸歯状波の生成
先の例において，鋸歯状波を生成する文を

y = signal.sawtooth(2*np.pi*f*t,width=0.5)
として実行すると，図 100 の (b) が表示される．
立ち上がり幅は連続的に変化させることができる．そのためには，時間軸配列の各要素に対応する立ち上がり幅の値を配列にしてキーワード引数 ‘width=’ に与える．
次の例は，正弦波 (sin(2πt) + 1)/2 で立ち上がり幅を変調する例である．
例．立ち上がり幅を連続的に変化させる例（先の例の続き）>>> f = 5Enter

←周波数（5Hz）の設定

Enter>>> y = signal.sawtooth(2*np.pi*f*t,width=m)>>> f = plt.figure(figsize=(5,2))

Enter←鋸歯状波の生成←作図の開始>>> r1 = plt.plot(t,m)

Enter←変調用正弦波のプロット>>> r2 = plt.plot(t,y)

Enter←変調結果の波形のプロット>>> r3 = plt.xlabel(’t’)>>> plt.show()

Enter

Enter

←グラフの横軸ラベル←作図の実行

この実行結果として図 101 が表示される．

図 101: 鋸歯状波の立ち上がり幅の変調
このグラフには，変調用の正弦波 (sin(2πt) + 1)/2 と，立ち上がり幅が変調された鋸歯状波が重ねて表示される．

157

WAV ファイル入出力ツール: scipy.io.wavﬁle3.2.2

scipy.io.wavﬁle は WAV 形式42 音声データファイルの入出力のための機能を提供する．Python 処理系には WAV 形
式音声ファイルを扱うために wave モジュール43 が標準的に提供されているが，scipy.io.wavﬁle の方が高機能である．

3.2.2.1

WAV 形式ファイル出力：

書き方：

write 関数write( ファイル名, サンプリング周波数, データ配列 )波形データの「データ配列」を「ファイル名」のファイルに出力する．
「サンプリング周波数」44 は整数値で与える．
出力する WAV ファイルの量子化ビット数45 は「データ配列」の要素の型から自動的に設定される．

1 秒の長さの 440Hz の正弦波のサウンドをサンプリング周波数 44.1KHz で出力する例を次に示す．
例．正弦波の波形を WAV 形式ファイルとして出力する← scipy.io.wavﬁle の読み込みEnter>>> from scipy.io import wavfile>>> import numpy as np

Enter← NumPy の読み込み>>> r = 44100; f = 440

Enter←サンプリング周波数 r とサウンドの周波数 f の設定>>> t = np.linspace( 0, 1, r )>>> yL = np.sin(2*np.pi*f*t)←時間軸の生成（0〜1 秒）

Enter
Enter

←正弦波の波形の生成>>> wavfile.write( ’scipyWavINT16.wav’, r, (32767*yL).astype(’int16’) ) Enter←出力 (1)>>> wavfile.write( ’scipyWavUINT8.wav’, r, (127*(yL+1)).astype(’uint8’) ) Enter←出力 (2)>>> wavfile.write( ’scipyWavFLT32.wav’, r, yL.astype(’float32’) ) Enter←出力 (3)「出力 (1)」は 16 ビット整数型の出力であり，市販の音楽 CD で標準的に採用されている形式である．
「出力 (2)」は符号なし 8 ビット整数型の出力であり，音質を犠牲にして出力データの大きさを小さく抑える場合に適している．波形データを整数型で出力する場合，波形の値は出力用の整数型の値の範囲でなければならない．これを調べるには

NumPy の iinfo 46 を使用すると良い．
「出力 (3)」は 32 ビット浮動小数点数による出力であり，高品質のサウンドデータ（いわゆるハイレゾリューショ
ンオーディオあるいはハイレゾ）を作成する場合に適している．
出力する音声の品質はデータ型だけでなく，サンプリング周波数にも依存する．サンプリング周波数は標準的には

44.1KHz，ハイレゾの場合は 48KHz 以上（96KHz など），音質を求めない場合は 22.05KHz 以下の値を採用する．
この例で作成した WAV 形式ファイルは，多くのサウンド再生用アプリケーションソフトで再生することができる．
【ステレオサウンドの出力】
左右 2 チャンネルのサウンドを出力するにはそれら波形データを 2 次元の配列として構成する．具体的には，[ [左 0, 右 0],[左 1, 右 1],：[左 n, 右 n] ]という形式でデータ配列を作成する．
例．ステレオサウンドの出力（先の例の続き）>>> yR = np.cos(2*np.pi*f*t)Enter←余弦関数の波形の生成>>> yST = np.hstack( (yL.reshape(-1,1), yR.reshape(-1,1)) ) Enter← 2 次元配列の波形>>> wavfile.write( ’scipyWavFLT32stereo.wav’, r, yST.astype(’float32’) ) Enter←出力

この例では余弦関数の波形データを変数 yR に作成している．これを右チャンネル，先の例で作成した yL を左チャンネルとして合成して 2 次元配列 yST を作成し，それを WAV 形式ファイルとして出力している．
42 Microsoft 社と IBM 社によって開発されたデータフォーマット
43 これに関しては拙書「Python3 入門」で解説しています．
44 1 秒間の音声を何個のデータとしてサンプリングするかの個数．
45 音声波形の 1 つの値を表現するビット長
46 「3.1.2.4 扱える値の範囲」（p.54）を参照のこと．

158

3.2.2.2

WAV 形式ファイル入力：

書き方：

read 関数read( ファイル名 )「ファイル名」の WAV 形式ファイルの内容を読み取って (サンプリング周波数, データ配列) のタプルを返す．先に作成した WAV 形式ファイルを読み込み，波形をプロットする例を次に示す．
例．WAV 形式ファイルの内容をプロットする（先の例の続き）>>> (r2,yST2) = wavfile.read( ’scipyWavFLT32stereo.wav’ )
Enter

44100

←単位は Hz(44100, 2)← WAV ファイルの読込み←サンプリング周波数の確認>>> r2>>> yST2.shapeEnter←データ配列の形状の確認

Enter← 2 列の 2 次元配列（左右 2 チャンネル）>>> yL2 = yST2[:,0]Enter←左チャンネルの取り出し>>> yR2 = yST2[:,1]Enter←右チャンネルの取り出し>>> import matplotlib.pyplot as plt← matplotlib の読込みEnter>>> (fig,ax) = plt.subplots( 2,1, figsize=(8,3) )>>> a00 = ax[0].plot(yL2[:300])

Enter←描画手順の開始

Enter←左チャンネルの波形のプロット（先頭 300 個）

Enter←右チャンネルの波形のプロット（先頭 300 個）>>> a01 = ax[0].set ylabel(’Left’)>>> a02 = ax[0].grid()>>> a10 = ax[1].plot(yR2[:300])>>> a11 = ax[1].set ylabel(’Right’)>>> a12 = ax[1].grid()>>> plt.show()

Enter←描画の実行

この実行の結果，図 102 のような波形のプロットが表示される．

図 102: ステレオサウンドの波形のプロット

3.2.2.3

32-bit ﬂoating-point の WAV 形式サウンドデータ

32-bit ﬂoating-point の WAV 形式サウンドデータは -1.0〜1.0 の範囲で波形の値が表現される．従って，この範囲を超える値はサウンドデータとしてはクリッピングされる．この様子を次に示す．
例．-2.0〜2.0 の正弦波形の WAV ファイルの作成（先の例の続き）>>> y1 = 2*np.sin(2*np.pi*f*t)

Enter←振幅の大きな正弦波形>>> wavfile.write( ’scipyWavFLT32over.wav’, r, y1.astype(’float32’) ) Enter ←ファイル出力
この処理で作成した WAV 形式ファイル ‘scipyWavFLT32over.wav’ をオープンソースの音声編集ソフト Audacity 47 で開いた様子を図 103 に示す．

47 公式インターネットサイト：https://www.audacityteam.org/

159

図 103: 振幅の大きな（-2.0〜2.0）正弦波形を Audacity で開いたところ-1.0〜1.0 の範囲からはみ出した波形の上下の部分がクリッピング（切り取り）されているのがわかる．また，これをサウンドとして再生するとクリッピングが原因となる音の歪みが起こる．ただし，32-bit ﬂoating-point の WAV 形
式サウンドデータは，クリッピングされた部分の波形の情報を保持しており，振幅を縮小して波形の値の範囲を -1.0
〜1.0 にすることで元の波形を再現することができる．このことを図 104 に示す．

図 104: 振幅を半分に縮小（-6db 増幅）したところ：元の波形が再現されている整数値として作成された WAV 形式データでは，クリッピングされた部分の波形情報は失われ，振幅を事後で縮小してもクリッピングされた部分の波形は復元されない．

ﬂoat32 の型で表現される数値の仮数部は 23 ビットの長さ48 があり，32-bit ﬂoating-point の WAV 形式サウンドデー
タはハイレゾサウンドとしての音質を実現することができる．また，先に示したように 0db を超えるレベルのサウン
ドの波形を保持できるので，整数型の WAV 形式に比べて有利な点が多い．ただし，32-bit ﬂoating-point の WAV 形
式サウンドデータは同じ再生時間の 16 ビット整数型 WAV 形式データに比べると 2 倍のデータサイズとなることに留意する必要がある．

48 IEEE 754 で規定されている．

160

数式処理ライブラリ： SymPy

3.3

SymPy は Python に数式処理機能を提供するパッケージ49 である．数式処理システム（CAS: Computer Algebra
System）とは，数式を記号的に処理するシステムであり，代数的な計算を記号のまま実行する．例えば，a + a という式を評価すると 2a という形（あるいは 2 ∗ a という形）で結果が得られる．

SymPy は，数式やそれを構成する記号を独特のオブジェクトとして扱うため，一般的に知られる数式処理システ
ム50 と比較すると，記号の扱いに違いがある．本書では他の数式処理システムとの違いを意識しながら，SymPyの使用方法ついて導入的なレベルで説明する．SymPy に関するより詳しい情報についてはインターネットサイト

http://www.sympy.org/ を参照のこと．
3.3.1

モジュールの読込みに関する注意

SymPy は多くの関数やメソッドを提供している．そのため，クラス名や関数名などが他のパッケージと重複する可能性が大きくなるので，Python に読み込む際には注意が必要である．例えば，

from sympy import *などとしてパッケージを読み込むと，オブジェクトの生成や関数呼び出しにおいてパッケージ名の指定を省略することができて操作が簡便である反面，他のモジュールを読み込んで併用する場合にクラスや関数の名前が衝突するという問題が起こる．Python に SymPy のみを読み込んで，数式処理ツールとして利用する場合は上記の形でモジュールを読み込んでも特に問題はないが，数式処理機能を応用プログラムに組み込んで利用するということを目的とする場
合は，名前の衝突に関しては注意を払う必要がある．すなわち，SymPy を読み込む際に，from sympy import 関数名,…
などとして，使用する関数名やクラス名を明に指定する方がよい．あるいは，

import sympy
としてパッケージを読み込んで，関数を呼び出す際に，

sympy. 関数名 (引数)としてパッケージ名を明に指定するのが良い．また，多くの機能が関数としてだけでなく，各クラスのメソッドとしても実装されているので，極力メソッドの形式で数式処理機能を使用するのが安全である．

3.3.2

基礎事項

SymPy による数式の計算には通常の算術記号（+, -, *, /）が使える．また冪乗は ’**’ である．ただし，他の数式処理システムと違う点として，Python の変数と，数式を構成する記号は全く別のものであるということがある．次の実行例について考える．
誤った操作の例>>> from sympy import *>>> x + x

Enter

Enter

← SymPy を読み込み各種名前を大域化する（注：好ましくはない）←数式の簡単化を試みる

Traceback (most recent call last):
File "<stdin>", line 1, in <module>
NameError: name ’x’ is not defined]

エラーメッセージが表示される

エラーメッセージが表示されているが，原因は，未定義の変数同士を加算しようとしたことにある．SymPy で記号的計算を実行するには，計算対象の記号を予め生成しておく必要がある．次の例について考える．

49 文献参照：“Open source computer algebra systems: SymPy”, David Joyner, Ondřej Čertı́k, et.al., ACM Communications in

Computer Algebra archive Volume 45 Issue 3/4, Sep./Dec. 2011, pp.225-234,ACM New York, USA
50 ウルフラム・リサーチ社の Mathematica，ウォータールー大学（カナダ）で開発された Maple，フリーソフトウェア（GNU GPL）のMaxima などが有名である．

161

正しい操作の例>>> x = Symbol(’x’)>>> x + xEnter←’x’ という記号を生成している←数式の簡単化を試みる

Enter←正しい結果が得られている

2*x

この例では，SymPy の記号オブジェクト’x’ を生成して，それを Python の変数 x に与えている．すなわち「変数 x に SymPy の記号オブジェクト ’x’ が代入されている」と考えると良い．他の数式処理システムでは，変数と代数記号の区別がないが，SymPy の利用においては，このことを常に念頭に置く必要がある．

3.3.2.1

記号オブジェクトの生成

sympy パッケージの Symbol 関数を用いることで数式処理のための記号オブジェクトを生成することができる．
書き方：

sympy.Symbol(文字列)

文字列として記述されたものを表す 1 つの数式記号オブジェクトを生成して返す．また関数 symbols を使用（先頭が小文字であることに注意）すると，複数の記号を空白で（あるいはコンマで）区切った形の文字列を引数に与えて，複数の数式記号を同時に生成することができる．この場合の戻り値は生成した記号のタプルである．またこの場合，引数に与えた文字列中に記述した順でシンボルオブジェクトが得られる．
書き方：

sympy.symbols(文字列)

数式記号を生成する例>>> import sympy←パッケージの読み込みEnter>>> w = sympy.Symbol(’w’)←数式記号の生成（1 個）Enter>>> (x,y,z) = sympy.symbols(’x y z’)←数式記号の生成（3 個）←記号的計算Enter>>> w + x + x

Enter

←計算結果

w + 2*x上の例に示したように，生成した記号オブジェクトは，同じ名前の変数に割り当てると，その記号を扱う上で判りやすい．このような割り当て処理を簡単な形で実行するために var 関数がある．
書き方：

sympy.var(文字列)引数に与える「文字列」は symbols 関数の場合に準じる．生成された記号オブジェクトは，同名の大域変数（グローバル変数）に割り当てられる．
例．記号オブジェクトを生成して，同じ名前の変数に割り当てる（先の例の続き）>>> sympy.var(’a,b’)(a, b)

Enter←記号オブジェクト ’a’，’b’ の生成←記号オブジェクトが生成された>>> a+b+a+b+a+2

Enter

3*a + 2*b + 2←それらを使った計算←計算結果

var 関数も先の symbols 関数と同様に，生成した記号オブジェクトのタプルを返す．
3.3.2.2

数式の簡単化（評価）

数式記号を生成すると，それらを算術記号（+, -, *, /）でつなげることで計算（簡単化，評価）されるが，もっと単純に，文字列として記述した数式を関数 simplify の引数に与えることでも計算結果が得られる．
書き方：

sympy.simplify(文字列)162

例．数式の簡単化>>> import sympy←パッケージの読み込み

Enter

←計算

Enter

>>> sympy.simplify(’a + b + a + c’)←計算結果

2*a + b + c

この例のような処理では，数式記号を明に生成しなくても良い．すなわち，simplify 関数を使用すると，より簡単に（文字列型の式から）数式オブジェクトを生成することができる．
※ 文字列型の式を SymPy の式に変換する，より基本的な関数 sympify が存在する．詳しくは SymPy のインターネットサイト
を参照のこと．

数式からのオブジェクトの取り出し
数式オブジェクトに対して atoms メソッドを使用すると，その数式に含まれるオブジェクトを集合の形で取得することができる．
例．数式から各種オブジェクトを取り出す>>> import sympy←パッケージの読み込みEnter>>> s = sympy.simplify(’a+b+a+2*b+c+pi+f(x)+g(y)’)
>>> s

←計算

←内容の確認Enter←計算結果が保持されている

2*a + 3*b + c + f(x) + g(y) + pi
{y, a, b, x, c}←記号の取り出しEnter>>> s.atoms(sympy.Symbol)←代数記号の集合（セット）が得られている←数値の取り出しEnter>>> s.atoms(sympy.Number){2, 3}

Enter←数値の集合（セット）が得られているEnter>>> s.atoms(sympy.Function){g(y), f(x)}←関数の取り出し←関数の集合（セット）が得られている

このように atoms メソッドの引数に sympy.Symbol, sympy.Number,sympy.Function を指定することで，各種オブジェ
クトの集合（セット）が得られるので，これを list 関数でリストに変換すると，数式を構成するオブジェクトのリス
トとして得ることができる．

3.3.2.3

式 f(x,y,...) の構造（頭部と引数列の取り出し）f(x,y,...) の形をした式の頭部と引数列はそれぞれ，func, args プロパティから得られる．
例．式の頭部と引数列の取り出し>>> import sympy←パッケージの読み込みEnter>>> s = sympy.simplify(’f(x,y,z)’)>>> sf = s.func>>> sf←頭部の取り出しEnter←結果を調べるEnter←頭部が得られているのがわかるf>>> sa = s.args>>> sa

←式の生成

Enter

Enter

←引数列の取り出し←結果を調べるEnter←引数の列（タプル）が得られている(x, y, z)

頭部が sf に，引数のタプルが sa に得られている．
式の頭部として得られたオブジェクトは，そのまま式の構成に利用できる．
（次の例）
例．式の再構成（先の例の続き）>>> sf( sa[0], sa[1], sa[2] )f(1, 2, 3)←式の再構成←元の式と同じものが生成されている

f(x, y, z)>>> sf( 1, 2, 3 )

Enter

Enter

←引数を変えて式を構成する例
←生成結果

163

定数

3.3.2.4

数式の中で使用する定数は以下の通り．
：

E

ネイピア数

pi ： 円周率
：

I

虚数単位

（Python の元来の虚数単位 j と混同しないこと）

oo ： 正の無限大 （厳密な意味では数ではない）
例．定数の使用>>> sympy.simplify(’sin(pi)’)Enter← sin(π) の計算

←計算結果

0

>>> sympy.simplify(’I * I’)Enter← i ∗ i の計算

←計算結果

-1

定数は sympy パッケージのオブジェクトとしても使用できる．すなわち，

sympy.E，sympy.pi，sympy.I，sympy.oo
として参照することができる．

本書では以降，

import sympy
として SymPy を読み込んで使用することを前提とする．

3.3.3

基本的な数式処理機能

先に説明した simplify に加えて，次に挙げるような基本的な数式処理機能が使用できる．

3.3.3.1

式の展開

expand メソッドを使用すると数式を展開することができる．
例．

>>> s = sympy.simplify(’(a+b)**10’)>>> s2 = s.expand()>>> s2Enter←数式の生成Enter←展開の処理←結果の確認Enter

a**10 + 10*a**9*b + 45*a**8*b**2 + 120*a**7*b**3 + 210*a**6*b**4 + 252*a**5*b**5 +210*a**4*b**6 + 120*a**3*b**7 + 45*a**2*b**8 + 10*a*b**9 + b**10←処理結果
同様の処理を

3.3.3.2

sympy.expand(s)として関数の形式で実行することもできる．

因数分解

factor メソッドを使用すると数式の因数分解ができる．
例．（先の例の続き）>>> s2.factor()(a + b)**10
同様の処理を

3.3.3.3

Enter←因数分解の処理←処理結果

sympy.factor(s2)として関数の形式で実行することもできる．

指定した記号による整理

collect メソッドを使用すると，指定した記号で整理することができる．

164

例．

>>> s = sympy.simplify(’(a+b+x)**2’).expand()←処理結果

a**2 + 2*a*b + 2*a*x + b**2 + 2*b*x + x**2

←記号 x で整理Enter>>> s.collect(’x’)←処理結果

a**2 + 2*a*b + b**2 + x**2 + x*(2*a + 2*b)同様の処理を

3.3.3.4←数式の生成：(a + b + x)2 の展開←結果の確認

Enter

>>> s

Enter

として関数の形式で実行することもできる．

sympy.collect(s,’x’)

約分：分数の簡単化 (1)cancel メソッドを使用すると，分数を約分することができる．複雑な分数
ax2 + 2axy + ay 2 + bx2 + 2bxy + by 2acx + acy + adx + ady + bcx + bcy + bdx + bdyが約分される様子を例示する．
例．

>>> s1 = sympy.simplify(’a*x**2 + 2*a*x*y + a*y**2 +b*x**2 + 2*b*x*y + b*y**2’)Enter←数式の生成 (分子)>>> s2 = sympy.simplify(’a*c*x + a*c*y + a*d*x + a*d*y +b*c*x + b*c*y + b*d*x + b*d*y’)
Enter←数式の生成 (分母)>>> s = s1 / s2>>> s

←複雑な分数の作成

Enter←結果の確認Enter(a*x**2 + 2*a*x*y + a*y**2 + b*x**2 + 2*b*x*y + b*y**2)/(a*c*x + a*c*y + a*d*x + a*d*y + b*c*x + b*c*y + b*d*x + b*d*y)Enter>>> s.cancel()←処理結果 (複雑な分数)←約分の実行←処理結果(x + y)/(c + d)
約分した結果がx+yc+dとして得られている．

3.3.3.5

部分分数

apart メソッドを使用すると，分数を部分分数にすることができる．
（ただし，複数の記号オブジェクトからなる分
数は処理できない）

分数

5x3 + 6x2 + x + 4
x4 + 4x3 + 4x2 + 4x + 3
が部分分数に変形される様子を例示する．
例．部分分数>>> s1 = sympy.simplify(’5*x**3 + 6*x**2 + x + 4’)

Enter←数式の生成 (分子)>>> s2 = sympy.simplify(’x**4 + 4*x**3 + 4*x**2 + 4*x + 3’)>>> s = s1 / s2
>>> s

Enter

← 1 つの長い分数の作成

Enter←結果の確認Enter(5*x**3 + 6*x**2 + x + 4)/(x**4 + 4*x**3 + 4*x**2 + 4*x + 3)>>> s3 = s.apart()>>> s3Enter←部分分数への変形

Enter←結果の確認-1/(x**2 + 1) + 4/(x + 3) + 1/(x + 1)
部分分数

←数式の生成 (分母)

←処理結果

4
1
1
+
+
− 2
x +1 x+3 x+1

165←処理結果 (1 つの長い分数)に変換されていることがわかる．
同様の処理を

3.3.3.6として関数の形式で実行することもできる．

sympy.apart(s)分数の簡単化 (2)（通分の処理を含む） 先の例（部分分数分解）でratsimp メソッドを使用すると，分数をまとめることができる．
得られた結果の s3 に対して ratsimp を適用した例を示す．
例．（先の例の続き）>>> s3.ratsimp()←簡単化の処理Enter(5*x**3 + 6*x**2 + x + 4)/(x**4 + 4*x**3 + 4*x**2 + 4*x + 3)

←処理結果

元の式に戻り，1 つの分数としてまとめられていることがわかる．
同様の処理を

3.3.3.7として関数の形式で実行することもできる．

sympy.ratsimp(s3)

代入（記号の置換）

subs メソッドを使用すると，記号（Symbol）を別の記号に置き換えることができる．
例．

Enter

>>> (a,b,x) = sympy.symbols(’a b x’)
←式の生成

Enter

>>> s = 2*a + 3*b←記号の生成←記号 a を記号 x に置き換える>>> s.subs(a,x)

Enter

3*b + 2*x

←処理結果>>> s.subs(a+b,x)Enter←式を別のものに置き換えることは…
←できない．

2*a + 3*b

この例の様に，式を別のものに置き換えることはできない．複数の記号の置換処理には，置換規則を辞書オブジェク
トにして与える．
例．（先の例の続き）>>> s.subs( {a:x,b:1} )←処理結果

2*x + 33.3.3.8←記号 a を記号 x に，b を 1 に置き換える

Enter

各種の数学関数

SymPy では，Python の数値演算で使用できる各種の数学関数と同じ名前のものが概ね使用できるが，対数関数はlog の表記を基本とする．ln の表記でも入力できるが，それは log として扱われる．
例．対数関数← ln の表記も使用できる>>> sympy.simplify(’ln(1)’)

Enter

0

←計算結果

>>> sympy.simplify(’ln(x)’)

Enterlog(x)← log の表記に統一される

3.3.3.9← ln を代数的に記述すると

式の型

SymPy で扱う式には様々な「型」があり，‘is ’ の接頭辞で始まるプロパティでそれを検査できる．
例．オブジェクトの型の検査>>> import sympy←モジュールの読込みEnter>>> s = sympy.Symbol(’x’)>>> s.is symbolTrue← s にシンボルをセット← s がシンボルかどうかを検査←真である>>> s.is number
False

Enter

Enter

Enter

← s が数値かどうかを検査

←偽である

166

この例が示すように，検査対象のオブジェクトの ‘is ’ で始まるプロパティからその型がわかる．is で始まるプロパ
ティの一部を表 28 に示す．
表 28: オブジェクトの型を検査する ‘is ’ プロパティ（一部）
プロパティ 解説

プロパティ

解説

is number

数値かどうかを検査する．

is symbol

シンボルかどうかを検査する．

is Add加算の式かどうかを検査する．

is Mul

乗算の式かどうかを検査する．

is Pow

べき乗の式かどうかを検査する．

is で始まるプロパティにはこの他にも様々な検査をするものがあるが，詳しくは SymPy のドキュメントの「assumptions」に関する解説を参照のこと．
3.3.4

解析学的処理

ここでは，微分と積分を基本とする解析学的な処理機能について説明する．

3.3.4.1

極限与えられた式の極限を求めるには limit メソッドを使用する．
書き方：

式.limit(対象の変数, 向かう極限)

次に，

1

lim

x→1 x − 1を求める例を示す．
例．

>>> s = 1 / (x - 1)>>> s.limit(x,1)←記号 x の生成Enter>>> x = sympy.symbols(’x’)←式 1/(x-1) の生成

Enter← x → 1 の極限を求める

Enter←処理結果：∞oo

ただしこの例の式では，x の数直線上における「右から左」の極限であり，「左から右」の極限では計算結果が異なる．
極限に向かう方向を指定して厳密に計算するには，limit メソッドに 3 番目の引数として ’+’ もしくは ’-’ を与える．
（次の例を参照）例．（先の例の続き）←「右から左」の極限>>> s.limit(x,1,’+’)

Enter

oo

←処理結果：∞>>> s.limit(x,1,’-’)

Enter

-oo

←処理結果：−∞

この例において同様の処理を

3.3.4.2←「左から右」の極限

sympy.limit(s,x,1,’-’)

として関数の形式で実行することもできる．

導関数

与えられた式を，ある変数を定義域として値域を与える関数として見た場合，diﬀ メソッドを使用して，その変数についての導関数を求める（偏微分する）ことができる．
例．導関数>>> x = sympy.symbols(’x’)>>> s = sympy.simplify(’sin(x)’)>>> s.diff(x)cos(x)

Enter←記号 x の生成

Enter
Enter

←式の生成

← x についての導関数を求める
←処理結果

167

これは，

d
sin (x)dxを求めた例である．
この例において同様の処理を

3.3.4.3

sympy.diff(s,x)

として関数の形式で実行することもできる．

微分操作の遅延実行

Derivative クラスを使用すると，導関数を求める処理（微分操作）を遅延実行することができる．
例．微分操作の遅延実行>>> s = sympy.simplify(’Derivative(sin(x),x)’)
>>> s

←式の生成

←結果の確認Enter←元のままの式が得られている

Derivative(sin(x), x)>>> s.doit()Enter←式の「実行」

Enter←処理結果：導関数が得られている

cos(x)

この例のように doit メソッドを使用すると微分操作が実行される．Derivative を用いた導関数の表現は，微分演算の抽象的な表現を数式として記述可能51 にする．これにより，微分方程式を記述することが可能となるだけでなく，後の「3.3.10.1 LATEX」のところで説明する書式変換などにおいても有効な表現手段を与える．

3.3.4.4

原始関数

先の導関数の算出と逆の処理をするには integrate メソッドを使用する．
例．
>>> x = sympy.symbols(’x’)>>> s = sympy.simplify(’cos(x)’)>>> s.integrate(x)Enter←記号 x の生成

Enter
Enter

←式の生成

← diﬀ(x) と逆の処理←処理結果

sin(x)

得られた値に定数項が付いていないので，厳密な意味ではこの処理では原始関数を求めたことにはならない．厳密な意味での原始関数を求めるには「3.3.5 各種方程式の求解」で説明する微分方程式の求解の方法を参照のこと．
この例において同様の処理を

3.3.4.5として関数の形式で実行することもできる．

sympy.integrate(s,x)

integrate の遅延実行

Integral クラスを使用すると，integrate による処理を遅延実行することができる．
例．integrate の遅延実行>>> s = sympy.simplify(’Integral(cos(x),x)’)>>> s←結果の確認Enter

Integral(cos(x), x)>>> s.doit()sin(x)

Enter

Enter

←元のままの式が得られている←式の「実行」←処理結果

51 関数に対する操作であるので，Derivative は広義の汎関数である．

168

←式の生成

定積分

3.3.4.6

integrate を使用して定積分を求めることができる．
 ∞1
例．
dx を求める
2x
1>>> x = sympy.symbols(’x’)←記号 x の生成

Enter

←無限大記号の生成

Enter>>> inf = sympy.simplify(’oo’)>>> s = sympy.simplify(’1/x**2’)←関数の生成Enter←定積分の実行Enter>>> s.integrate( (x,1,inf) )

←積分結果

1

遅延実行の形で同様の処理をおこなうこともできる．
（次の例参照）>>> s = sympy.simplify(’Integral(1/x**2,(x,1,oo))’)>>> s.doit()

Enter←遅延実行のための式の生成←処理の実行

Enter
←積分結果

1
級数展開

3.3.4.7与えられた式の級数展開（テイラー展開／マクローリン展開）を得るには series メソッドを使用する．
例．exp(x) の展開>>> x = sympy.symbols(’x’)>>> s = sympy.simplify(’exp(x)’)>>> s.series(x)←記号 x の生成

Enter

←式の生成

Enter

←級数展開

Enter

1 + x + x**2/2 + x**3/6 + x**4/24 + x**5/120 + O(x**6)>>> s.series(x,0,8)← 6 番目の項まで計算される←級数展開：0 を起点に 8 番目まで

Enter

1 + x + x**2/2 + x**3/6 + x**4/24 + x**5/120 + x**6/720 + x**7/5040 + O(x**8)>>> s.series(x,1,6)←処理結果←級数展開：1 を起点に 6 番目まで

Enter

E + E*(x - 1) + E*(x - 1)**2/2 + E*(x - 1)**3/6 + E*(x - 1)**4/24 +E*(x - 1)**5/120 + O((x - 1)**6, (x, 1))
この例において同様の処理を3.3.5のようにして関数の形式で実行することもできる．

sympy.series(s,x)

各種方程式の求解

ここでは，各種の方程式の求解のためのメソッドを紹介する．

3.3.5.1

代数方程式の求解

代数方程式の解を求めるには solve 関数を使用する．

1) f (x) = 0 の x についての求解例．x + 1 = 0 を x について解く>>> x = sympy.symbols(’x’)←記号 x の生成Enter>>> s = sympy.simplify(’x+1’)

Enter

←処理結果

←式の生成
← s = 0 を満たす x の求解>>> sympy.solve(s,x)

Enter

[-1]

←解は x = -1 の 1 個

2) f1 (x) = f2 (x) の x についての求解等式を表現するには Eq を使用する．

169

例．2x + 1 = 3x − 5 を x について解く>>> x = sympy.symbols(’x’)←記号 x の生成Enter

←方程式の生成Enter>>> s = sympy.simplify(’Eq(2*x+1,3*x-5)’)← s を満たす x の求解>>> sympy.solve(s,x)

Enter

[6]

←解は x = 6 の 1 個

solve 関数は 4 次の代数方程式まで一般的に求解する．
例．2 次の代数方程式 ax2 + bx + c = 0 の求解>>> x = sympy.symbols(’x’)←記号 x の生成

Enter

Enter

>>> s = sympy.simplify(’a*x**2 + b*x + c’)>>> sympy.solve(s,x)←方程式の生成← s = 0 を満たす x の求解Enter[(-b + sqrt(-4*a*c + b**2))/(2*a), -(b + sqrt(-4*a*c + b**2))/(2*a)]←解は 2 個連立方程式の求解

solve 関数に与える方程式と変数をリストにして与えることで連立方程式を解くことができる．
例．

>>> eq = sympy.simplify(’[a*x + b*y - e, c*x + d*y - f]’)>>> sympy.solve(eq,v){x:←方程式の生成←変数リストの生成Enter>>> v = sympy.simplify(’[x,y]’)

Enter

←求解

Enter

(-b*f + d*e)/(a*d - b*c), y:(a*f - c*e)/(a*d - b*c)}←解が得られている

このように，解は辞書オブジェクトの形で得られる．

3.3.5.2

微分方程式の求解

微分方程式の解を求めるには dsolve 関数を使用する．この関数には，解くべき方程式と，求めるべき解の関数を引数に指定する．
例．

1df (x) −
= 0 の f (x) についての求解dxsin (x)>>> f = sympy.simplify(’f(x)’)←求めるべき関数 f (x) の生成

Enter>>> eq = sympy.simplify(’Derivative(f(x),x)-1/sin(x)’)
Enter>>> sol = sympy.dsolve(eq,f)>>> solEnter←微分方程式の生成

←求解

←解の確認

Enter

Eq(f(x), C1 + log(cos(x) - 1)/2 - log(cos(x) + 1)/2)

←解

解として，

1
1
log (cos (x) − 1) − log (cos (x) + 1)22が得られている．
（C1 は定数項）
f (x) = C1 +dsolve 関数の引数に与える方程式は Eq(...) の形でも良い．
不定積分によって原始関数を求める場合は dsolve 関数を使用する．

3.3.5.3階差方程式の求解（差分方程式，漸化式）

rsolve 関数を使用すると，階差方程式（差分方程式）を解くことができる．これは漸化式の一般化も含む．
例．f (n + 1) − rf (n) = 0 の f (n) についての求解>>> f = sympy.simplify(’f(n)’)

Enter>>> s = sympy.simplify(’f(n+1)-r*f(n)’)>>> sympy.rsolve(s,f)
C0*r**n←求めるべき関数 f (n) の生成

Enter
←求解

Enter
←解

170

←階差方程式の生成解が C0 · rn として得られている．
初期値を辞書オブジェクトの形で与えることもできる．
例．（先の続き）初期値 f (0) = a を与える>>> ini = sympy.simplify(’{f(0):a}’)>>> sympy.rsolve(s,f,ini)

Enter

a*r**n←解Enter←初期値の生成←求解

解が a · rn として得られている．

3.3.6

線形代数

Matrix クラスを使用すると行列が表現できる．例えば，


a b
c

d

を SymPy のオブジェクトとして生成する例を次に示す．

>>> sympy.var(’a b c d’)(a, b, c, d)Enter←記号の生成←生成された記号Enter>>> m1 = sympy.Matrix([[a,b],[c,d]])>>> sympy.pprint(m1)
Enter


a b
←表示結果
c d

←行列の生成←整形表示

この例の様に pprint 関数を使用すると，行列を整形表示する．この関数は行列以外の数式にも使用することができる．

Matrix オブジェクトの和，差，積には通常の算術記号が使用できる．
例．行列の和，差，積（先の例の続き）>>> sympy.var(’e f g h’)(e, f, g, h)Enter←記号の生成←生成された記号Enter>>> m2 = sympy.Matrix([[e,f],[g,h]])←行列の生成>>> sympy.pprint(m2)
Enter


e f
←表示結果
g h

←整形表示

>>> sympy.pprint( m1 + m2 )
a+e b+f←和
c+g d+hEnter←行列同士の和>>> sympy.pprint( m1 - m2 )a−e b−f←差
c−g d−h

Enter

←行列の差

>>> sympy.pprint( m1 * m2 )
ae + bg af + bh
←積
ce + dg cf + dh

Enter

←行列の積

3.3.6.1

行列の連結Matrix.hstack，Matrix.vstack メソッドを用いると水平，垂直の方向に行列を連結することができる．

171

例．水平方向の連結（先の例の続き）>>> mh = sympy.Matrix.hstack( m1, m2 )Enter

←行列の水平連結Enter←行列の垂直連結>>> sympy.pprint(mh)Enter ←整形表示
a b e f
←連結結果（2 行 4 列）
c d g h例．垂直方向の連結（先の例の続き）>>> mv = sympy.Matrix.vstack( m1, m2 )>>> sympy.pprint(mv)Enter ←整形表示
⎡
⎤
a b
⎢
⎥
⎢ c d ⎥⎢⎥
←連結結果（4 行 2 列）⎢⎥
⎣ e f ⎦
g h
3.3.6.2行列の形状

行列の形状（行，列のサイズ）は shape プロパティ52 から得られる．
例．shape プロパティ（先の例の続き）>>> mv.shape(4, 2)

Enter←行数と列数を調べる←4行2列

この例のように，行と列のサイズのタプルが得られる．

3.3.6.3

行列の要素へのアクセス

Matrix オブジェクトの行や列は row(n)，col(m) メソッドで n 行，m 列（n,m はインデックス位置）を参照することができる．
例．行の参照（先の例の続き）>>> sympy.pprint( mv.row(1) )←参照した行c d

Enter← mv のインデックス 1 番目の行を整形表示

Enter← mv のインデックス 0 番目の列を整形表示

例．列の参照（先の例の続き）>>> sympy.pprint( mv.col(0) )
⎤
⎡
a
⎥
⎢
⎢ c ⎥
⎥
⎢
←参照した列⎥⎢⎣ e ⎦grow，col メソッドは Matrix オブジェクトを返す．
Matrix オブジェクトにはスライス ‘[n]’ を付けて n 番目の要素にアクセス（参照，値の設定）することができる．
例．Matrix オブジェクトの要素の参照（先の例の続き）>>> mv[0],mv[1],mv[2],mv[3],mv[4],mv[5],mv[6],mv[7](a, b, c, d, e, f, g, h)Enter← mv の全要素を並べたタプル←行列の左上から右下にかけて順に並んでいる

52 NumPy の ndarray が持つ shape プロパティと似ている．

172

例．Matrix オブジェクトに直接的に要素を与える（先の例の続き）>>> mv[2] = 2

Enter← mv のインデックス位置 2 の要素として「2」を与える>>> mv[3] = 3

Enter← mv のインデックス位置 3 の要素として「3」を与える>>> sympy.pprint(mv)Enter ← mv を整形表示
⎡
⎤
a b
⎢
⎥
⎢ 2 3 ⎥⎢⎥
←指定した位置に要素が与えられている
⎢
⎥
e
f
⎣
⎦
g h
3.3.6.4

行列式

行列オブジェクトに対して det メソッドを使用すると行列式を得ることができる．
例．行列式（先の例の続き）>>> m1.det()
a*d - b*c
3.3.6.5←行列式を求める

Enter

←処理結果

逆行列

正則な行列オブジェクトに対して inv メソッドを使用すると逆行列を得ることができる．
例．逆行列（先の例の続き）>>> im = m1.inv()Enter←行列式を求める>>> sympy.pprint(im)Enter ←整形表示
⎤
⎡
d
b
−
⎢ ad − bc
ad − bc ⎥
←表示結果
⎦
⎣
a
c
−
ad − bcad − bc
3.3.6.6

行列の転置

Matrix オブジェクトに対して transpose メソッドを使用すると，それを転置したものを返す．また，元の Matrix オ
ブジェクトには変更はない．
例．行列の転置>>> sympy.var(’a b c d e f g h i’)(a, b, c, d, e, f, g, h, i)←記号の生成Enter←生成された記号>>> m = sympy.Matrix([[a,b,c],[d,e,f],[g,h,i]])>>> sympy.pprint( m )
Enter
⎡
⎤
a b c
⎢
⎥
⎢ d e f ⎥
←表示結果
⎣
⎦
g h i
>>> sympy.pprint( m.transpose() )
⎡
⎤
a d g
⎢
⎥
⎢ b e h ⎥←転置された行列⎣⎦
c f i
3.3.6.7

Enter←行列の作成

←整形表示

Enter

←転置処理（整形表示）

ベクトル，内積n 次元のベクトルは n 行 1 列の Matrix オブジェクトとして扱う．

173

例．3 次元のベクトル←記号の生成Enter>>> sympy.var(’a b c d e f’)←生成された記号(a, b, c, d, e, f)>>> v1 = sympy.Matrix([a,b,c])Enter←ベクトル v1 = (a, b, c) の作成>>> v2 = sympy.Matrix([d,e,f])Enter←ベクトル v2 = (d, e, f ) の作成>>> sympy.pprint(v1)Enter←ベクトル v1 の整形表示
⎡
⎤
a
⎢
⎥
⎢ b ⎥
← 3 次元のベクトル（3 行 1 列の Matrix）⎣⎦
c
ベクトルの内積は dot メソッドで求める．
例．ベクトルの内積（先の例の続き）>>> v1.dot(v2)←ベクトルの内積 v1 · v2 を求める

Enter
←内積

a*d + b*e + c*f

固有値，固有ベクトル3.3.6.8

行列オブジェクトに対して eigenvals メソッドを使用すると，固有値を求めることができる．固有ベクトルも共に求める場合は eigenvects メソッドを使用する．
例．固有値，固有ベクトルの算出>>> m = sympy.Matrix([[3,1],[2,4]])←整形表示>>> sympy.pprint(m)
Enter


3 1
←表示結果
2 4
>>> m.eigenvals()
{5:

1, 2:

1}

Enter

←固有値を求める←固有値と代数的重複度53 の辞書オブジェクトが得られる>>> ev = m.eigenvects()←固有値と固有ベクトルを求めるEnter>>> sympy.pprint(ev)
Enter
⎡⎛
⎛
⎡⎡
⎤⎤⎞
−1
⎢⎜
⎜
⎢
⎥⎥⎟
⎢⎝2, 1, ⎢⎣⎣⎦⎦⎠ , ⎜
⎣
⎝5,
1

3.3.7

←行列式を求める

Enter

←整形表示
⎡⎡
⎤ ⎤ ⎞⎤1⎢ ⎢ 2 ⎥ ⎥ ⎟⎥⎢⎥ ⎥ ⎟⎥
1, ⎢⎣⎣⎦ ⎦ ⎠⎦
1

←表示結果

総和

総和を表す式として Sum がある．これは総和を意味する式であり，doit メソッドにより評価される．
書き方：

Sum( 式,( 変数, 初期値, 終了値 ) )例えば Sum( f(k), (k, k0, n) ) という式は，
n

f (k)
k=k0

を意味する．
例．初項 a1 ，公差 d の等差数列 a1 , a2 , · · · , an の n 番目までの総和>>> s = sympy.simplify(’Sum( a1+(k-1)*d, (k,1,n) )’) Enter ←一般項 a1 + (k − 1)d の形で与える>>> sympy.simplify( s.doit() )Enter

n*(2*a1 + d*n - d)/2

←評価結果

←評価の実行

この例でもわかるように，Sum は遅延実行される式であり，doit により実際に評価される．
53 algebraic multiplicity

174

3.3.8

パターンマッチ

SymPy には数式の記号代数的な構造に沿ったパターンマッチのための機能が提供されている．例えば，
3x2 + 5x + 1という式があった場合に，x の 2 次の部分の係数とそれ以外の部分を取り出すことを考える．
この数式の記号的代数的な構造を

P1 P2 2 + P 3というパターンと見做して P1 , P2 , P3 に該当する（マッチする）部分を元の式から抽出すると，

P1 = 3, P2 = x, P3 = 5x + 1のように対応する．SymPy ではこのような形でのパターンマッチが可能である．ここで示した例にある P1 , P2 , P3
は SymPy においては Wild オブジェクトとして扱われる．次に SymPy による例を手順を追って示す．
【例】3x2 + 5x + 1

P1 P2 2 + P3

をにマッチさせる

手順 0. モジュールの読込みと対象となる式の用意>>> import sympy← SymPy モジュールの読込み

Enter

Enter

>>> f = sympy.sympify(’3*x**2+5*x+1’)←式 3x2 + 5x + 1 を f にセット

手順 1.Wild オブジェクトの用意>>> P1 = sympy.Wild(’P1’)

Enter←マッチングのための Wild オブジェクト P1 を生成>>> P2 = sympy.Wild(’P2’)

Enter←マッチングのための Wild オブジェクト P2 を生成>>> P3 = sympy.Wild(’P3’)

Enter←マッチングのための Wild オブジェクト P3 を生成

ここで，Wild オブジェクト P1 の内容を確認してみると← Wild オブジェクト P1 の内容確認>>> P1EnterP1← Wild オブジェクト P1 の内容

このように，アンダースコア ‘ ’ が付いた形で表示されるオブジェクトである．
手順 2. マッチングの実行

r←マッチングの結果である r の内容を確認

Enter

{P2 :

x, P1 :

3, P3 :

Enter>>> r[P3]5*x + 1← match メソッドでマッチングするEnter>>> r = f.match( P1*P2**2+P3 )5*x + 1}

← P1,P2,P3 への対応が辞書オブジェクト r として得られている．

←マッチング結果から P3 に対応する部分を取り出す．

←対応する部分が得られている

このように，対象となる数式に対して match メソッドを使用することでパターンマッチが実行される．match メソッ
ドの引数には Wild オブジェクトから構成されるパターンを与える．

match メソッドの引数に与えるパターンの式には，通常の Symbol オブジェクトを用いても良い．
（次の例参照）
例．3x2 + 5x + 1

を

P1 x2 + P3>>> X = sympy.Symbol(’x’)にマッチさせる（先の例の続き）

Enter>>> r = f.match( P1*X**2+P3 )←通常の Symbol としての変数記号 x の生成Enter← match メソッドでマッチングする

>>> r

Enter

←マッチングの結果である r の内容を確認{P1 :3, P3 :

5*x + 1}

3.3.9
3.3.9.1← P1,P3 への対応が辞書オブジェクト r として得られている．

数値計算
素因数分解

整数の素因数分解には factorint 関数を使用する．

175

例．整数の素因数分解

Enter>>> sympy.factorint( 1234567890 )
{2:

1, 3:

2, 5:

1, 3607:1, 3803:1}←整数の素因数分解←素因数とその指数が辞書オブジェクトとして得られる

これは 1,234,567,890 を 2 × 32 × 5 × 3607 × 3803 に分解した例である．

3.3.9.2

素数

sympy ライブラリは，素数を生成する関数やそれを判定する関数を提供する．関数 primerange は指定した範囲にある素数のジェネレータを作成する．
書き方：

primerange( N1, N2 )N1 以上 N2 未満の範囲にある素数を取得するためのジェネレータを返す．
例．指定した範囲にある素数の取得

Enter>>> p = sympy.primerange(2,20)
Enter>>> list( p )← 2 以上 20 未満の素数のジェネレータを取得←それをリストに変換←得られた素数のリスト[2, 3, 5, 7, 11, 13, 17, 19]primerange の第 2 引数には「それ未満」の値を与える関係上，第 2 引数に素数を与えるとその値は得られない．
例．2 以上 19 未満の素数>>> list( sympy.primerange(2,19) )Enter←素数のリストを作成←得られた素数のリスト[2, 3, 5, 7, 11, 13, 17]

素数は 2，3，5，7，… と続くが，最初の 2 を「1 番目の素数」として「N 番目の」素数を求める関数 prime がある．
書き方：

prime( N )この関数は「N 番目の」素数を返す．
例．100,000 番目の素数

sympy.prime(100000)← 100,000 番目の素数Enter←得られた素数

1299709与えられた数が素数かどうかを判定するには関数 isprime を使用する．
例．素数かどうかを判定← 23 は…

Enter>>> sympy.isprime( 23 )←素数であるTrue← 24 は…

Enter>>> sympy.isprime( 24 )←素数ではない

False

指定した数以下の範囲に存在する素数の個数を調べるには関数 primepi を使用する．
例．素数の個数を調べる>>> sympy.primepi(19)Enter← 19 以下の範囲にある素数の個数を求める←これだけ素数がある

8

N 以下の範囲にある全ての素数の積を素数階乗と言い N # と書く．sympy には「N 番目までの素数の全ての積」を求める関数 primorial が存在し，先の primepi と共に用いることで素数階乗を求めることができる．
例．5# を求める>>> n = sympy.primepi(5)
>>> n

Enter

←確認

3
>>> sympy.primorial(n)30← 5 以下の素数の個数を求める

Enter

←3個

Enter

← 3 番目までの素数の積を求める←得られた値

176

sympy は，ここで紹介したもの以外にも素数や合成数に関する関数を提供する．
3.3.9.3

近似値

数式の近似値（数値）を求めるには evalf メソッドを使用する．
例． 円周率を 70 桁の精度で求める>>> sympy.pi.evalf(70)←数値近似を求める

Enter

3.141592653589793238462643383279502884197169399375105820974944592307816
例．Matrix オブジェクトの数値近似>>> s = sympy.sympify(’sqrt(2)’); t = sympy.sympify(’sqrt(3)’)

Enter>>> u = sympy.sympify(’sqrt(5)’); v = sympy.sympify(’sqrt(7)’)

Enter>>> sympy.pprint( m )
 √
√ 
2
3
√
√
5
7

Enter

√

←行列を作成Enter>>> m = sympy.Matrix([[s,t],[u,v]])√
2, t = 3√√← u = 5, v = 7
←s=

←整形表示

>>> sympy.pprint( m.evalf(20) )Enter ←数値近似

1.4142135623730950488 1.7320508075688772935
2.2360679774997896964 2.6457513110645905905←数値近似した Matrix

当然ではあるが，数値化できない式には無意味である．
（次の例参照）
例．数値近似が得られないもの>>> s = sympy.simplify(’a+b’)>>> s.evalf(70)←記号のみからなる数式←数値近似を求めようとしても…

←できない．

a + b
3.3.10

Enter

Enter

書式の変換出力

SymPy の式を別の言語（MathML,LATEX など）の表現に変換する方法が用意されている．
3.3.10.1

LATEX

sympy のオブジェクトとして表現した部分積分の公式は，Eq(Integral(u,v),v*u-Integral(v,u))であるが，これを LATEX の式に変換する例を次に示す．
例．LATEX 表現の作成>>> s = sympy.sympify(’Eq(Integral(u,v),v*u-Integral(v,u))’)
>>> s

Enter

Enter

←内容確認
←内容表示

Eq(Integral(u, v), u*v - Integral(v, u))>>> print(sympy.latex(s))

Enter\int u\, dv = u v - \int v\, du← LAT X の形式に変換して表示

E
←内容表示

これを LATEX で処理すると，u dv = uv − v duと表示される．このように latex 関数を使用することで LATEX の表現を生成できる．

3.3.10.2

MathMLsympy のオブジェクトを MathML の式に変換するには mathml 関数を使用する．
177←部分積分の公式

例．MathML 表現の作成（先の例の続き）>>> print(sympy.mathml(s))← MathML の形式に変換して表示

Enter<apply><eq/><apply><int/><bvar><ci>v</ci></bvar><ci>u</ci></apply><apply><minus/><apply><times/><ci>u</ci><ci>v</ci></apply><apply><int/><bvar><ci>u</ci></bvar><ci>v</ci></apply></apply></apply>
3.3.11←内容表示

グラフのプロット

SymPy は関数のグラフを描く機能（グラフのプロット）を提供する．1 変数の関数のプロット（2 次元のグラフ）を作成するには plot 関数を使用する．
書き方：

plot(式, (変数, 最小値, 最大値) )例．正弦関数のプロット>>> f = sympy.sympify(’sin(x)’)>>> sympy.plot(f,(’x’,-4,4))

Enter

Enter

← f に正弦関数の式を与える←プロット開始<sympy.plotting.plot.Plot object at 0x000002C53BBF1E10> ←戻り値
この処理の結果，図 105 の (a) のようなグラフが表示される．plot 関数にはキーワード引数 xlabel, ylabel を指定することができ，次の例のように実行すると軸のラベルを表示する（図 105 の (b)）ことができる．
例．正弦関数のプロット（軸ラベル付き）>>> sympy.plot(f,(’x’,-4,4),xlabel=’x’,ylabel=’sin(x)’)

Enter←プロット開始<sympy.plotting.plot.Plot object at 0x000002C53FE00080> ←戻り値(a) 軸ラベル指定なし(b) 軸ラベル指定あり

図 105: プロットの表示

2 変数の関数のプロット（3 次元のグラフ）を作成するには plot3d 関数を使用する．この関数は，モジュール
sympy.plotting にあるため，使用に際してはこのモジュールをインポートしておく必要がある．
書き方：

plot3d(式, (変数 1, 最小値, 最大値), (変数 2, 最小値, 最大値) )


例．cos
x2 + y 2 のプロット>>> from sympy.plotting import plot3d

Enter←モジュールのインポート>>> f = sympy.sympify(’cos((x**2+y**2)**(1/2))’)Enter← f に関数の式を与える>>> plot3d(f,(’x’,-4.5,4.5),(’y’,-4.5,4.5),xlabel=’x’,ylabel=’y’,title=’z’)↑プロット開始<sympy.plotting.plot.Plot object at 0x000002C53DAF6828> ←戻り値
178

Enter

この処理の結果図 106 のようなグラフが表示される．

図 106: 3 次元のプロット

3.3.11.1

グラフを画像ファイルに保存する方法

plot 関数や plot3d 関数で作成したグラフを，画像ファイルとして保存するには，それら関数の戻り値に対して save
メソッドを使用する．
（次の例参照）
例．グラフの保存（先の例の続き）>>> g = plot3d(f,(’x’,-4.5,4.5),(’y’,-4.5,4.5),xlabel=’x’,ylabel=’y’,title=’z’)↑描画結果を g に保持>>> g.save(’sympyFig01.eps’)Enter← eps 形式で保存>>> g.save(’sympyFig01.png’)Enter← png 形式で保存

Enter

save メソッドの引数に，保存先のファイル名を与える．画像ファイルのフォーマットは，ファイル名の拡張子によって自動的に判断される．
（扱えないフォーマットもあるので注意）

179

4

セキュリティ関連

4.1

hashlib

hashlib は暗号学的なメッセージダイジェストを生成するためのモジュールであり，Python に標準的に提供されている．hashlib が提供するダイジェスト作成アルゴリズムは，MD5, SHA1, SHA224 , SHA256, SHA384, SHA512 である．
メッセージダイジェストを生成する機能は，パスワード文字列の秘匿化54 や，文書のデジタル署名の生成に必要となる．このモジュールは使用に先立って，次のようにして必要なモジュールを読み込んでおく必要がある．

import hashlib
4.1.1

基本的な使用方法

ここでは，パスワード文字列を秘匿化する処理を例に挙げて hashlib の基本的な使用方法について説明する．
例．パスワード文字列 ’MyPassword’ の秘匿化（MD5 による）>>> import hashlibEnter←モジュールの読み込み>>> m = hashlib.md5(b’MyPassword’)>>> m.digest()Enter←ダイジェスト生成用オブジェクトの生成（MD5）Enter←ダイジェスト生成b’HP=￥xfdXr￥x0b￥xd5￥xff5￥xc1￥x02￥x06ZR￥xd7’>>> m.hexdigest()

Enter←得られたダイジェスト（バイト列）← 16 進数表現でダイジェスト生成’48503dfd58720bd5ff35c102065a52d7’←得られたダイジェスト（文字列）

このように，ハッシュ化のアルゴリズム（この例では md5）の名前のコンストラクタの引数に秘匿化したい（ハッシュ化したい）文字列をバイト列形式で与えた後，digest メソッドでダイジェスト（秘匿化されたデータ）を生成する．あるいは hexdigest メソッドを使用すると 16 進数表現の文字列としてダイジェストを得ることができる．

4.2

passlib

UNIX 系 OS（Linux など）の /etc/shadow に使用するために，パスワードのハッシュ文字列（メッセージダイジェ
スト）を生成するには passlib が利用できる．このモジュールに関する情報は，公式インターネットサイト

https://passlib.readthedocs.io/から得られる．
【基本的な考え方】
平文のパスワードとソルト55 （salt）から，暗号化アルゴリズムによってメッセージダイジェストを生成する．

4.2.1

使用できるアルゴリズム

passlib で使用できる暗号化アルゴリズムは passlib.hosts モジュールが提供する次のような関数群（表 29）で調べることができる．

54 UNIX 系 OS（Linux など）の /etc/shadow に使用するためにパスワードのハッシュ文字列を生成するには，後の passlib を用いるのが良い．

55 ソルト：メッセージダイジェストから平文を見破るパスワードクラックを難しくするために，メッセージダイジェストを生成する際に与える文字列．

180

表 29: passlib で使用できる暗号化アルゴリズムを調べる関数
対象の OS関数

Linux

passlib.hosts.linux context.schemes()

FreeBSD

passlib.hosts.freebsd context.schemes()

OpenBSD

passlib.hosts.openbsd context.schemes()

表 29 の関数を実行した例を次に示す．
例．暗号化アルゴリズムを調べる>>> import passlib.hostsEnter←モジュールの読込みEnter>>> passlib.hosts.linux context.schemes()← Linux 用(’sha512 crypt’, ’sha256 crypt’, ’md5 crypt’, ’des crypt’, ’unix disabled’)↑使用できるアルゴリズムのタプル>>> passlib.hosts.freebsd context.schemes()Enter← FreeBSD 用(’bcrypt’, ’md5 crypt’, ’bsd nthash’, ’des crypt’, ’unix disabled’)↑使用できるアルゴリズムのタプル>>> passlib.hosts.openbsd context.schemes()Enter← OpenBSD 用(’bcrypt’, ’md5 crypt’, ’bsdi crypt’, ’des crypt’, ’unix disabled’)↑使用できるアルゴリズムのタプル
次に，平文のパスワードとソルトからメッセージダイジェストを生成する例を示す．
例．MD5 アルゴリズム56 によるメッセージダイジェストの生成>>> import passlib.hashEnter←モジュールの読込み>>> passlib.hash.md5 crypt.hash( ’MyPassword’, salt=’abc’ )’$1$abc$lKbExFu3EBz4Nynw0YLsN0’

Enter←暗号化を実行←生成されたメッセージダイジェスト

この例では，md5 crypt アルゴリズムを用いて，平文パスワード ‘MyPassword’ とソルト ‘abc’ からメッセージダイ
ジェスト ‘$1$abc$lKbExFu3EBz4Nynw0YLsN0’ を生成している．

56 MD5：多くの UNIX 系 OS のパスワード管理で採用されているアルゴリズム．

181

プログラムの高速化／アプリケーション構築

5

Python インタプリタによるプログラムの実行時間は，同様のアルゴリズムを実装した C 言語のプログラムと比べて数十倍〜百数十倍程度大きい．このことは計算量の多い処理を行う際に大きな問題となる．ここでは，プログラムの実行時間を小さくするための方法についていくつか紹介する．

5.1

CythonPython のプログラムの実行時間を短縮するための方法の 1 つに Cython 処理系 の利用がある．Cython 処理系は公式のインターネットサイト http://cython.org/ から入手できるが，必要となる C 言語処理系57 も Cython の導入に先立って準備しておくこと．本書では Cython 処理系について導入的に解説する．Cython の詳細に関しては公式サイ
トをはじめとするドキュメント58 を参照のこと．

Cython 処理系は Python の言語仕様を拡張した Cython 言語を扱う．Cython 言語で記述されたソースプログラム
は一旦 C 言語のソースプログラムに翻訳され，更にそれが C 言語処理系によって実行形式のプログラムに翻訳される．最終的に Cython のプログラムは Python 処理系のためのモジュールとなり，Python のプログラムから呼び出すことができる．Cython 処理系を用いて作成されたモジュールプログラムの実行速度は，通常の Python プログラムの実行に比べて数倍からそれ以上となる．

5.1.1

使用例

サンプルプログラムを挙げ，Cython を用いることでプログラムの実行時間が短縮されることを例示する．次に示す

ﬁb.py はフィボナッチ数列を表示するプログラム59 である．
プログラム：ﬁb.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18

# coding : utf -8
import time
# フィボナッチ数列の生成
def fib1 ( n ):if n == 0 or n == 1:
return ( 1 )else :
f = fib1 (n -1) + fib1 (n -2)
return ( f )def fib ( n ):t1 = time . time ()for i in range ( n ):print ( fib1 ( i ) )t = time . time () - t1
print (t , ’ 秒 ’ )このプログラムをモジュールとして Python 処理系に読み込んで実行した例を次に示す．

57 例：Windows 環境では Visual Studio，Apple Macintosh の場合は Xcode．
58 Cython の日本語ドキュメントサイト：http://omake.accense.com/static/doc-ja/cython/
59 ここに示すプログラムは，フィボナッチ数の再帰的な関数定義をそのまま実装したものである．フィボナッチ数の生成は動的計画法などのアルゴリズムを採用すると大幅に高速化できるが，ここでは大きな実行時間を要する例として，敢えてこの形のプログラムを示す．

182

>>> import fib

Enter←モジュールとして読込み>>> fib.fib(35)Enter←フィボナチ数列表示の開始

1
1
2
3
：
（途中省略）：
57028879227465
8.10300588607788 秒←要した時間

次に，このプログラムを Cython によって高速化する手順を示す．
【手順】
１．Cython のプログラムとして用意する
先のプログラム ﬁb.py の拡張子を ’.pyx’ にしたものを用意する．プログラム自体は変更しない．
今回は Cython のプログラム ﬁbC.pyx として用意する．
２．翻訳用スクリプトを作成して実行する

Cython プログラムを翻訳するための次のような Python プログラム setup.py を用意する．
from distutils.core import setup
from distutils.extension import Extension
from Cython.Distutils import build ext
setup(
cmdclass = {’build ext’:build ext},

ext modules = [Extension(’fibC’, [’fibC.pyx’])]# ←プログラム名を指定する)
下から 2 行目にあるように，翻訳対象のプログラムの名前を指定する．
この翻訳用スクリプトを，build ext –inplace という引数とオプションを付けて実行する．
例．翻訳処理py setup.py build ext --inplaceEnter←翻訳処理の開始

running build ext
cythoning fibC.pyx to fibC.cbuilding ’fibC’ extension
C:￥Program Files (x86)￥Microsoft Visual Studio 14.0￥VC￥BIN￥x86 amd64￥cl.exe /c：（途中省略）：
ﬁbC.obj : warning LNK4197: エクスポート ’PyInit ﬁbC’ が複数回指定されています。
一番最初の指定を適用します。
ライブラリ build￥temp.win-amd64-3.6￥Release￥ﬁbC.cp36-win amd64.lib とオブジェクト
build￥temp.win-amd64-3.6￥Release￥ﬁbC.cp36-win amd64.exp を作成中
コード生成しています。
コード生成が終了しました。
この処理の結果，モジュール ﬁbC が生成される．
３．Python 処理系で実行する

Cython で作成したモジュール ﬁbC を Python 処理系に読み込んで実行する例を次に示す．

183

>>> import fibC

Enter

←モジュールとして読込み>>> fibC.fib(35)Enter←フィボナチ数列表示の開始

1
1
2
3
：
（途中省略）：
57028879227465(2.273406505584717, ’ 秒’)←要した時間

先に示した ﬁb.py を Python 処理系で実行する場合と比べて，実行速度が約 3.56 倍になっていることがわかる．

5.1.2

高速化のための調整

Cython は Python のプログラムを C 言語のプログラム変換して翻訳する．このため，Cython のプログラムを記述する際に変数や関数の型を明に宣言することにより，より効率的に C 言語のプログラムに変換されることがある．先の ﬁb.py を元に，変数や関数の型を明に宣言する形にしたプログラム ﬁbC2.pyx を次に示す．
プログラム：ﬁbC2.pyx
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19

# coding : utf -8
import time
# フィボナッチ数列の生成
cdef int fib1 ( int n ):# 型を指定した関数の定義
if n == 0 or n == 1:
return ( 1 )else :
f = fib1 (n -1) + fib1 (n -2)
return ( f )def fib ( int n ):cdef intit1 = time . time ()for i in range ( n ):print ( fib1 ( i ) )t = time . time () - t1
print (t , ’ 秒 ’ )# 引数の型の指定# 変数の型の指定

このプログラムでは，変数や関数の仮引数の型を明に宣言し，外部から呼び出されない関数の型を指定している．型の指定には ‘cdef’ を用いる．このプログラムを翻訳して実行した結果の例を次に示す．

>>> import fibC2

Enter←モジュールとして読込み>>> fibC2.fib(35)Enter←フィボナチ数列表示の開始

1
1
2
3
：
（途中省略）：
57028879227465(0.1199653148651123, ’ 秒’)←要した時間はじめに示した ﬁb.py を Python 処理系で実行する場合と比べて，実行速度が約 77.17 倍になっていることがわか
る．

184

5.2

Numba

Numba は LLVM 60 を用いて Python のプログラムを実行するためのモジュールであり，関連の情報はインターネッ
トの公式サイト http://numba.pydata.org/ から入手できる．本書では Numba について導入的に解説する．Numba に関する詳しいことは公式サイトを参照のこと．
基本的な使用方法

5.2.1

Numba は JIT コンパイラ61 を使用して Python のプログラムを実行する．具体的には，Python のソースプログラ
ム中に JIT コンパイラに対する指示をデコレータとして記述するという方法を取る．この方法によると，元々Python
で記述したプログラムをあまり変更することなく実行時間の短縮が望める．ここでは先に挙げたフィボナッチ数を計算するプログラム ﬁb.py を Numba によって高速化する過程を例示する．

ﬁb.py を Numba で実行するために改訂したものが次に示す ﬁbN1.py である．
プログラム：ﬁbN1.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21

# coding : utf -8
from numba import jit
import time
# フィボナッチ数列の生成@jit
def fib1 ( n ):if n == 0 or n == 1:
return ( 1 )else :
f = fib1 (n -1) + fib1 (n -2)
return ( f )@jit
def fib ( n ):t1 = time . time ()for i in range ( n ):print ( fib1 ( i ) )t = time . time () - t1
print (t , ’ 秒 ’ )解説：プログラムの 3 行目で Numba のパッケージを読み込んでいる．7 行目と 15 行目にある ‘@jit’ は直下に記述した関数を JIT コンパイルの対象とすることを指示するデコレータである．
このプログラムを実行した結果の例を次に示す．

>>> import fibN1

Enter←モジュールとして読込み>>> fibN1.fib(35)Enter←フィボナチ数列表示の開始

1
1
2
3
：
（途中省略）：
57028879227465
0.15616226196289062 秒←要した時間はじめに示した ﬁb.py を実行する場合と比べて，実行速度が約 51.9 倍になっていることがわかる．
60 C 言語をはじめとする各種言語のためのコンパイラ基盤である．
．元々はイリノイ大学（米）で開発され，オープンソースとして公開されている．
61 「実行時コンパイラ」（Just-In-Time コンパイラ）．ソフトウェアの実行時にコードのコンパイルを行い実行速度の向上を図る

コンパイラのこと．

185

型指定による高速化

5.2.2

JIT コンパイルする対象の関数の引数や戻り値のデータ型を指定することで，プログラムの実行時間が更に短縮できる場合がある．関数の型指定をする形で先の ﬁbN1.py を改訂したプログラムを ﬁbN2.py に示す．
プログラム：ﬁbN2.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21

# coding : utf -8
from numba import jit , i8
import time
# フィボナッチ数列の生成@jit ( ’ i8 ( i8 ) ’)def fib1 ( n ):if n == 0 or n == 1:
return ( 1 )else :
f = fib1 (n -1) + fib1 (n -2)
return ( f )@jit ( ’ i8 ( i8 ) ’)def fib ( n ):t1 = time . time ()for i in range ( n ):print ( fib1 ( i ) )t = time . time () - t1
print (t , ’ 秒 ’ )解説：プログラムの 3 行目で Numba のパッケージを読み込み，7 行目と 15 行目にデコレータを記述している点は先のﬁbN1.py と共通するが，関数の引数と戻り値の型を ‘i8’ で指定している．これは「8 バイト整数型」を意味する表記である．
（詳しくは公式サイトを参照のこと）※ Numba による高速化の度合いは対象となる関数や使用する他のパッケージに大きく依存する点に留意すること．

5.3

ctypesctypes は標準のパッケージであり，C 言語と互換性のあるデータ型を提供し，動的リンク/共有ライブラリ内の関数呼び出しを可能にする．本書では ctypes について導入的に解説する．ctypes に関する詳しい情報は Python の公式
サイトのドキュメントなどを参照すること．

5.3.1

C 言語による共有ライブラリ作成の例

C 言語で記述した関数を GNU の C コンパイラによって共有ライブラリにする手順を例示する．フィボナッチ数を求める C 言語のプログラム（関数）を ﬁbCC.c に示す．
プログラム：ﬁbCC.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

# include< stdio .h >long fib0 ( n )long n ;{if ( n == 0
return (} else if (return (} else {return (
}
}

)
1
n
1

{
);
== 1 ) {);fib0 (n -1) + fib0 (n -2) );void fib ( n )

186

16
17
18
19
20
21
22
23

long n ;{long c ;for ( c = 0; c < n ; c ++ ) {printf ("% ld \ n " , fib0 ( c ));}}このプログラムを gcc コマンドによってコンパイルし，他の言語処理系から使用できる共有ライブラリを作成するには，コンパイルオプション ‘-shared’ を指定する．
例．MinGW 環境下（Windows）での共有ライブラリの作成

gcc -O2 -shared -o fibCC.dll fibCC.c
この処理が正常に終了すると共有ライブラリ ﬁbCC.dll が作成される．

5.3.2

共有ライブラリ内の関数を呼び出す例

ctypes モジュールの CDLL クラスを使用することで，外部の共有ライブラリを Python 処理系に読み込み，共有ラ
イブラリ内の関数を呼び出すことができる．CDLL クラスのインスタンス（CDLL オブジェクト）を生成する際に，
コンストラクタに外部の共有ライブラリを指定する．先の例で作成した共有ライブラリを読み込んで関数を呼び出す

Python 側プログラムの例を ﬁbCCpy.py に示す．
プログラム：ﬁbCCpy.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16

# coding : utf -8# モジュールの読込み
import ctypes
import time
# 共有ライブラリの読込み
ex = ctypes . CDLL ( ’ fibCC . dll ’)
t1 = time . time ()# 共有ライブラリ中の関数の呼び出し
ex . fib (35)t = time . time () - t1
print (t , ’ 秒 ’ )このプログラム例では，共有ライブラリ ﬁbCC.dll を読み込んで CDLL オブジェクト ex を生成し，それに対するメソッドとして関数名を指定することで，関数 ﬁb を呼び出している．このプログラムを実行した例を次に示す．

1
1
2
3
：
（途中省略）：
57028879227465
0.07100534439086914 秒←要した時間はじめに示した ﬁb.py を実行する場合と比べて，実行速度が約 114.127 倍になっていることがわかる．

5.3.3

引数と戻り値の扱いについて

実用的な形で Python と C 言語の連携をするためには，相互にデータの受け渡しをする必要がある．ここでは，C
言語で作成した共有ライブラリと Python プログラムとの間で変数の値や配列を受け渡しするための基本的な方法を187

紹介する．
次に示す C 言語のプログラム ctypesTest01.c は，引数として受け取った値を処理して値を返す 3 つの関数を実装したものである．

C のプログラム：ctypesTest01.c
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

# include# include< stdio .h >< string .h >/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -** 整 数 （ int）の受け渡し** - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/int excgInt ( a )int a ;{
int r ;
r = 2 * a;printf (" C 側 )\ t \ t 与 え ら れ た 整 数 % d を 2 倍 し ま す : % d \ n " ,a , r );return ( r );}/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -** 浮 動 小 数 点 数 （ double）の受け渡し** - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/double excgDouble ( a )double a ;{double r ;r = 2.0 * a ;printf (" C 側 )\ t \ t 与 え ら れ た 浮 動 小 数 点 数 % lf を 2 . 0 倍 し ま す : % lf \ n " ,a , r );return ( r );}/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -** 文 字 列 （ char * ） の 受 け 渡 し** - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/char* excgString ( a )
char
*a;
{
static char r [256];
strcpy (r , a );strcat (r ," <- を 返 し ま す ． " ) ;printf (" C 側 )\ t \ t 与 え ら れ た 文 字 列 \ ’% s \ ’ を 加 工 し ま す : % s \ n " ,a , r );return ( r );}このプログラムで実装した関数は次の 3 つである．
・ int excgInt( int a ):引数 a の値を 2 倍した値を返す関数．

・ double excgDouble( double a ):引数 a の値を 2.0 倍した値を返す関数．

・ char *excgString( char *a ):引数 a で示す文字列を加工したもののポインタ返す関数．

これらの関数を呼び出す Python のプログラム ctypesTest01.py を次に示す．

Python 側プログラム：ctypesTest01.py
1
2
3
4
5
6

# coding : utf -8# モジュールの読込み
import ctypes# 共有ライブラリの読込み

188

7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25

ex = ctypes . CDLL ( ’ ctypesTest01 . dll ’)# 整数の受け渡し
r = ex . excgInt ( 4 )# 戻 り 値 は 暗 黙 で int 型
print ( ’ p y t h o n 側 )\ t 戻 り 値 : ’ , r )# 浮動小数点数の受け渡し
ex . excgDouble . restype = ctypes . c_doublea = ctypes . c_double (2.3)
r = ex . excgDouble ( a )print ( ’ p y t h o n 側 )\ t 戻 り 値 : ’ , r )# 戻 り 値 を double と 設 定# 引 数 を double に 変 換# 関数呼び出し# 文字列の受け渡し
ex . excgString . restype = ctypes . c_char_pa0 = ’ 元 の 文 字 列 ’ . encode ( ’ utf -8 ’)
a = ctypes . c_char_p ( a0 )r0 = ex . excgString ( a )r = r0 . decode ( ’ utf -8 ’)print ( ’ p y t h o n 側 )\ t 戻 り 値 : ’ , r )

#
#
#
#

戻 り 値 を char * と 設 定
送るデータを作成
そ れ を char * に 変 換関数呼び出し解説：
整数（int 型）の値を受け渡しする方法は単純であり，10 行目の記述の通りである．整数以外の型の引数や戻り値を扱う場合は，関数呼び出しに先立って準備のための処理が必要となる．
【共有ライブラリの関数の戻り値の扱い】

C 言語で記述した関数の戻り値の型は restype 属性で指定する．今回のプログラム（ctypesTest01.py）の場合，excgDouble 関数は double 型の値を返すので，14 行目にあるように restype として ctypes.c double を設定している．
同様に，文字列のポインタを返す関数 excgString には，20 行目にあるように restype として ctypes.c char p を設定している．
● 関数からの戻り値の型の指定

CDLL オブジェクト. 共有ライブラリの関数名.restype = ctypes. 型指定
C 言語の型を意味する ctypes の表現（一部）を表 30 に示すが，更に詳しい情報については Python の公式サイトを参照すること．
表 30: ctypes における C 言語のための型の指定：

ctypes での型

C 言語における型

ctypes での型

C 言語における型

c int

int 型

c longlong 型c uintunsigned int 型

c ulong

unsigned long 型

c shortshort int 型

c ushort

unsigned short int 型

c ﬂoatﬂoat 型c doubledouble 型

c char, c byte

char 型c ubyteunsigned char 型

c char p

char のポインタ型

c void p

void のポインタ型

先のプログラム ctypesTest01.py を実行した例を次に示す．

C 側)python 側)与えられた整数 4 を 2 倍します:
戻り値: 8C 側)python 側)与えられた浮動小数点数 2.300000 を 2.0 倍します:
戻り値: 4.6

C 側)python 側)与えられた文字列 ’ 元の文字列’ を加工します:
戻り値: 元の文字列 <- を返します．

8
4.600000

元の文字列 <- を返します．

【記憶の管理について】
先のプログラム例 ctypesTest01.c，ctypesTest01.py では，文字列の処理結果は関数 excgString 内の static の配列に189

格納されている．この形の実装では記憶の管理（配列の管理）が C 言語側に委ねられていることになるが，データ構造の管理を全て Python 側で行うには，Python 側のデータ構造のポインタのみを C の関数に渡すという形で実装する必要がある．また，C のプログラム側で malloc 関数などで記憶域を確保するというのも記憶域の解放といった管理を C 側に委ねなければならないので，Python との連携を安全な形で実現するには余り好ましくない．
次に，Python 側のリストを C 言語の配列のポインタとして受け渡す方法について説明する．

5.3.3.1

配列データの受け渡し

Python 側のリストなど，多数の要素を持ったデータ構造を C 言語の関数に渡すには，C 言語のポインタの形に変換する必要がある．また，C 言語の関数で処理した配列を Python 側で受け取るには，やはり配列のポインタとしてPython プログラムが受け取り，それをリストなどのデータ構造に変換する必要がある．
ここでは，double 型の配列に格納された値から正弦関数の値を算出して，同じく double 型の配列として作成するプログラムを例に挙げ，C 言語の関数との間で配列を受け渡しする方法を紹介する．定義域の値の配列から正弦関数の値の配列を作成する C 言語のプログラム ctypesTest02.c を次に示す．

C のプログラム：ctypesTest02.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20

# include# include< stdio .h >< math .h >/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -** 配列の受け渡し** - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/int excgArray ( a , n , r )double *a , * r ;
int
n;
{
int
x;
for ( x = 0; x < n ; x ++ ) {r [ x ] = sin ( a [ x ] );}printf (" C 側 )\ t \ t 正 弦 関 数 の 値 の 列 を 算 出 し ま し た ． : % d 個 \ n " , x );return ( x );}このプログラムは，定義域のデータを保持する配列のポインタを double *a に受け取って正弦関数の値を算出する関数 excgArray を実装したものである．計算結果も配列に格納するが，そのための配列の記憶域も呼び出し元（Python
プログラム側）が用意したものを使用する．
（配列のポインタを仮引数 r に受け取る）すなわち，Python 側で用意した配列のポインタを関数 excgArray に渡すので，C 言語プログラムの側では，配列の確保といった記憶の管理はしない．

C 言語の関数 excgArray を呼び出す Python プログラム ctypesTest02.py を次に示す．
Python 側プログラム：ctypesTest02.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

# coding : utf -8# モジュールの読込み
import ctypes
import matplotlib . pyplot as plt# 共有ライブラリの読込み
ex = ctypes . CDLL ( ’ ctypesTest02 . dll ’)# 引数と戻り値の型の設定
ex . excgArray . argtype = [ ctypes . POINTER ( ctypes . c_double ) ,ctypes . c_int , ctypes . POINTER ( ctypes . c_double ) ]# 引数の型を設定
ex . excgArray . restype = ctypes . c_int# 戻 り 値 を double と 設 定# 配列データの生成（リスト）

190

16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34

# 定義域用ax = [ x /100.0 for x in range (628) ]# リストを Cの配列（ポインタ）に変換
n = len ( ax )# 要素の個数（長さ）ar_t = ctypes . c_double * n# 配列の型の生成
ax2 = ctypes . byref ( ar_t ( * ax ) )# Cに渡す定義域の配列（ポインタ）# 得られた値域のデータを保持する配列の用意
ay2 = ar_t ()# Cに渡す値域の配列（ポインタ）# Cの関数の呼び出し
n2 = ex . excgArray ( ax2 , n , ay2 )ay = list ( ay2 )# 値域の配列をリストに変換

print ( ’ P y t h o n 側 )\ t 戻 り 値 : ’ , n2 )# 可視化
plt . plot ( ax , ay )plt . show ()解説：
このプログラムでは，リスト ax に 0〜2π の範囲の数値を 0.01 刻みで作成し，それを C の関数に渡すことができるポインタ ax2 として変換している．計算結果の正弦関数の値を格納する配列のポインタを ay2 に受け取り，それをPython のリスト ay に変換している．定義域のリスト ax と値域のリスト ay から matplotlib を使って関数のグラフとして可視化している．
プログラムの実行の結果，標準出力に次のように表示される．

C 側)
Python 側)正弦関数の値の列を算出しました．:
戻り値: 628

628 個

また，プロットしたグラフが図 107 のような形で表示される．

図 107: プロットの表示【配列のポインタを C の関数の引数に与えるための処理】
呼び出す関数の引数の型を argtype 属性にリスト形式で設定する．
● 関数の引数の型の指定

CDLL オブジェクト. 共有ライブラリの関数名.argtype = 引数の型指定のリスト
関数 excgArray は191

int excgArray( double *a, int n, double *r )のような型として定義されているので，引数の型に応じて次のように argtype 属性を設定する．

[ ctypes.POINTER(ctypes.c double), ctypes.c int, ctypes.POINTER(ctypes.c double) ]これを行っているのがプログラム ctypesTest02.py の 11〜12 行目である．また，配列へのポインタであることを指定するために POINTER(型指定) という表現を用いる．
プログラムの 20 行目では，C の関数の引数に与える配列の型をサイズを含めて ar t として定義している．
● 配列とサイズの型の定義
型指定 * サイズ
この型を用いて 21 行目では定義域のリスト ax から C に渡す配列 ax2 を生成し，24 行目では，計算結果を格納する
配列 ay2 を生成している．
● C 言語に渡す形式への変換

byref( 型 ( *リスト ) )27 行目では，ax2, ay2，それにデータの個数 n を引数に与えて C 言語の関数 excgArray を呼び出している．計算結果が格納されている配列 ay2 の内容を 28 行目で Python のリスト ay に変換している．
最後に 33〜34 行目でグラフをプロットしている．

192

5.4

PyInstaller

PyInstaller を用いると，Python のスクリプト（〜.py）から単独で動作するアプリケーションプログラム（Windowsの場合は〜.exe）を生成（アプリケーションのビルド）することができる．

PyInstaller に関する情報は，公式インターネットサイト
https://www.pyinstaller.org/から得られる．
簡単な使用例

5.4.1

サンプルスクリプト apptest00.py を用いて，アプリケーションをビルドする例を示す．

Python スクリプト：apptest00.py
1
2
3
4
5
6
7
8
9
10
11

# coding : utf -8# モジュールの読込みfrom math import *while True :s = input ( ’ 式 （ e x i t で 終 了 ） > ’)if s == ’ exit ’:breakelse :
v = eval ( s )print ( v )このスクリプトは，標準入力（ターミナルウィンドウ）から入力された文字列を式として計算する「簡易電卓」のようなものであり，‘exit’ を入力すると終了する．通常のように，これを Python インタプリタで実行すると次のようになる．
例．Python インタプリタでの実行（Windows の場合）

C:￥Users￥katsu>py apptest00.py

Enter

式（exit で終了）> 1+2

←式の入力

3

Enter

← OS のコマンドラインから Python 処理系を起動←計算結果

式（exit で終了）> sqrt(2)1.4142135623730951

←式の入力

←計算結果

式（exit で終了）> exit

C:￥Users￥katsu>

Enter

Enter

←終了

← OS のコマンドプロンプトに戻る．

次に，PyInstaller を用いて apptest00.py をビルドする例を示す．
例．PyInstaller によるビルド（Windows の場合）

C:￥Users￥katsu>pyinstaller apptest00.py

Enter←アプリケーションのビルド開始

125 INFO: PyInstaller: 3.4←ビルド処理に関するメッセージの表示が続く
125 INFO: Python: 3.6.6
125 INFO: Platform: Windows-10-10.0.17134-SP0：（途中省略）：
30532 INFO: Building COLLECT because COLLECT-00.toc is non existent
30532 INFO: Building COLLECT COLLECT-00.toc
30657 INFO: Building COLLECT COLLECT-00.toc completed successfully.
C:￥Users￥katsu>← OS のコマンドプロンプトに戻る．

この後，作業をしたディレクトリのサブディレクトリ build（無ければ作成される）の下に，Python スクリプトと同名のディレクトリが作成され，その中に PyInstaller が作業に使用したファイル群が生成される．また，作業をした
ディレクトリのサブディレクトリ dist（無ければ作成される）の下に，Python スクリプトと同名のディレクトリが作成され，その中にアプリケーションを構成するファイル群（DLL などを含む）が生成される．その中にビルドされ193

たアプリケーションのファイル（Windows の場合は〜.exe）が含まれる．

5.4.1.1

単一の実行ファイルとしてビルドする方法

単一の実行ファイルとしてアプリケーションをビルドするには，PyInstaller の処理を開始するコマンドラインにオプション ‘--onefile’ を与える．この場合，dist ディレクトリ内の Python スクリプトと同名のディレクトリに，単一の実行ファイルが作成される．
（例．図 108）

図 108: 単一の実行ファイルとしてビルドされた例（Windows の場合）
注意）Python スクリプトが使用するモジュールによっては，ビルドの段階で更なる作業が必要となることがある．詳
しくは PyInstaller の公式インターネットサイトの情報や，使用するモジュールに関する情報を調べること．

194

対話作業環境（JupyterLab）

6

Python を利用するには，プログラムを記述・編集するためのテキストエディタと，処理を実行するためのコマンド
ツール62 が必要となる．これらツールの機能を統合して，プログラムの開発と実行の操作性を高めるための対話作業環境として JupyterLab がある．

JupyterLab は，IPython 63 を取り込んで構築された，Web ベースのインターフェースを持つ作業環境であり，プ
ログラムの開発と実行に関するほぼ全ての作業（ファイルやディレクトリに関する操作も含む）を Web ブラウザ上で行うことができる．また，matplotlib や pandas をはじめとするパッケージの利用においては，作業を実行している表
示領域の中に図や表を表示することができ，視認性を向上する効果も得られる．更に，一連の作業内容をノートブッ
ク（Jupyter Notebook）というデータファイルとして保存管理することができ，過去に行った処理の再現や，作業の継続が簡単な形で実現できる．
導入方法をはじめとする JupyterLab に関する詳しい情報は，Jupyter の公式 Web サイト64 から得られる．

6.1

基礎事項

JupyterLab は Web アプリケーションとして実装されている．Web アプリケーションは，
1.

Web ブラウザ

ユーザと対話するフロントエンド （クライアント）

2.

Web サーバ

処理を実行するバックエンド（サーバ）という 2 つのシステム要素から成るもの（クライアント・サーバモデル）であり，JupyterLab も実行時にはクライア
ントの部分とサーバの部分が稼働する．具体的には，コマンドラインから JupyterLab を起動するとサーバ部分が稼働をはじめ，直後にフロントエンドとなる Web コンテンツが Web ブラウザ上に表示されるという流れとなる．

図 109: サーバとクライアントの連携 (通常の場合)
一般的な理解としては，クライアントシステムとサーバシステムは，別の場所に設置された別々のコンピュータで稼働するもの（図 109）65 として考えられることが多いが，JupyterLab の使用においては，それぞれが同一のコンピュー
タ内で実行されるケース（図 110）となる．

図 110: 同一のコンピュータ内でサーバとクライアントが連携するケース

62 Windows の場合は「コマンドプロンプトウィンドウ」，Mac の場合は「ターミナル」などが代表的なコマンドツールである．
63 対話作業環境の中心的機能を提供するソフトウェア．
（http://ipython.org/）
64 http://jupyter.org/

65 通常の場合 Web サービスは，コンテンツを配信しているサーバシステム（管理団体が運営する Web サーバ）と，それを閲覧する

Web ブラウザ（手元の端末装置）の連携によって実現されている．

195

6.1.1

起動と終了

JupyterLab を起動するには，コマンドシェル（コマンドのウィンドウ）で次のようなコマンドを発行する．
jupyter lab Enter
これに続いて，次のような JupyterLab の起動メッセージが表示される．
[I 18:47:58.048 LabApp] JupyterLab beta preview extension loaded from c:￥program files￥python36￥lib￥site-pac…
[I 18:47:58.048 LabApp] JupyterLab application directory is c:￥program files￥python36￥share￥jupyter￥lab：（途中省略）：[I 18:47:58.313 LabApp] Use Control-C to stop this server and shut down all kernels (twice to skip confirmation).
[C 18:47:58.315 LabApp]
Copy/paste this URL into your browser when you connect for the first time,
to login with a token:
http://localhost:8888/?token=7420a0d25ccefb7cdf9ae1406e8a63bdefc0372237157220[I 18:48:00.405 LabApp] Accepting one-time-token-authenticated connection from ::1[I 18:48:03.440 LabApp] Build is up to date

これで JupyterLab の Web サーバ部が起動し，更にこの後 Web ブラウザが起動して JupyterLab を使用するためのコンテンツが表示（クライアント部が実行）される．JupyterLab のサーバ部が起動している状態であれば，当該サーバプロセスの URL にアクセスすることで JupyterLab を使用することができる．上に挙げた起動メッセージの例の中にhttp://localhost:8888/?token=7420a0d25ccefb7cdf9ae1406e8a63bdefc0372237157220という部分があるが，それがこの例におけるサーバプロセスの URL 66 である．

JupyterLab の使用を終了するには，Web ブラウザを終了するだけでなく，サーバプロセスを起動したコマンドウィ
ンドウで CTRL + C を数回押下する必要がある．
（この操作でサーバプロセスが終了する）

6.1.2

表示領域の構成と操作方法

Web ブラウザに表示された JupyterLab のウィンドウの例を図 111 に示す．
Launcher

図 111: Web ブラウザで表示した JupyterLab のウィンドウ

JupyterLab のウィンドウは大きく分けて次のような 3 つの領域から成る．
● メニューバー（Menu Bar）
「File」,「Edit」,「View」,「Run」… とメニューが並んでいる横長の領域（図 112）．

66 ローカルホストでサーバを稼働しているので，URL のホストアドレスの部分が localhost となっている．

196

図 112: メニューバー（Menu Bar）

● 左サイドバー（Left Sidebar）
各種の管理機能の領域．
（図 113 (a)）● 主作業域（Main Work Area）
主たる作業領域．
（図 113 (b)）(a) 左サイドバー（Left Sidebar）(b) 主作業域（Main Work Area）

図 113: サイドバーと作業域
この内，主作業域で主だった作業を行う．JupyterLab を開始した時点では，この部分にはノートブック（Notebook），
コンソール（Console），Terminal，Text Editor の 4 つのものが表示されている．
（後述：「ランチャー」タブ）ノー
トブックは特に重要で，Python との対話をする機能であり，利用者と処理系のやりとり（対話過程）をノートブックのデータファイルとして保存することができる．このノートブックは，再度開いて処理の再現や継続を可能とするものである．コンソールもノートブックと同様に，利用者と Python が対話するものであるが，より単純な Python のコマンドウィンドウであり，処理過程の保存といった管理機能は無い．

Terminal は OS のコマンドシェル67 の機能であり，OS 上のコマンド作業を可能にする．また Text Editor はその名の通りテキストエディタであり，Python のプログラムを編集68 することができる．

6.1.2.1

ノートブックの使用例

JupyterLab 起動時の状態では，主作業域（Main Work Area）にはランチャー（Launcher）のタブが表示されている．この中から「Notebook」のセクションにある「Python 3」のボタンをクリックすると図 114 のようなノートブッ
クが表示される．

図 114: ノートブックの開始
67 macOS や Linux といった UNIX 系 OS ではコマンドシェルとして bash（sh） が起動する．Windows の場合は PowerShellなどが起動する．ただし，実際の利用においてはどのようなコマンドシェルが起動するかを確かめること．

68 コード体系や Tab の扱いに関する設定に注意すること．

197

この例では，主作業域に Untitled.jpynb というタイトルを持つノートブックが表示されている．これは，Untitled.jpynbというノートブックが作成されたことを意味しており，左サイドバーに同じ名前のファイルが作成されたことが表示されている．ノートブックには[ ]:と表示されており，これの右側に Python の文や式を入力することができる．
例．1 + 2 の計算[1]: 1 + 2[1]:3

文や式を入力して Shift + Enter を押下すると，入力したものが実行される．
（ Enter のみでは単なる改行となり，実行されない）
処理の結果として値が返されれば例のように[番号]:（結果の値）と表示される．
例．print 関数の実行[2]: print(’ これは JupyterLab のテストです．’)
これは JupyterLab のテストです．
処理の結果が入力のすぐ下に表示されている．値は返されないので ‘[番号]:’ は表示されない．
例．matplotlib のグラフのインライン表示[3]: import matplotlib.pyplot as plt
import numpy as np[4]: x = np.arange(-2.15,2.16,0.01)
y = x*(x-2)*(x-1)*(x+1)*(x+2)[5]: plt.plot(x,y)[5]:[<matplotlib.lines.Line2D at 0x2b552a70470>]

これは，numpy ライブラリで関数の値を算出した後，matplotlib で可視化した例である．この例の ‘[3]’ では必要なライブラリの読込みを行っている．‘[4]’ では，numpy ライブラリを用いて関数 y = x(x − 2)(x − 1)(x + 1)(x + 2)の定義域 x と値域 y を −2.15 ≤ x ≤ 2.15 の範囲で生成しており，‘[5]’ では，matplotlib ライブラリを用いてそれを作図している．
ノートブックの入力セル ‘[ ]:’ の領域に入力する文や式の行数については利用者が自由に決めて良い．今回の例では，「パッケージの準備」や「値の生成」などを 1 つのまとまりとして入力しているが，文や式を個々別々に入力して実行しても問題はない．
ノートブックやコンソールに記録された ‘[n]:’ の領域はセル（Cell）と呼ばれ，再度の実行や評価が可能である．

198

6.1.2.2

カーネル（Kernel）について

ノートブックやコンソールは Python インタプリタを介して文の実行や式の評価を行っている．この際，JupyterLab
は Python インタプリタをカーネル（Kernel）として起動している．すなわち，ノートブックやコンソールはあくま
でインターフェースとして利用者との対話を保持するものであり，実際の実行や評価は JupyterLab の背後で起動された Python インタプリタで行っている．この場合の Python インタプリタが JupyterLab から見た場合のカーネルである．
カーネルは，開いているそれぞれのノートブックやコンソールに対して 1 つずつ起動され，それぞれ別々の実行状態を保持している．すなわち，変数への値の割当てといった 1 連の処理の脈絡は，開いているノートブックやコンソー
ルで固有のものとなる．従って，1 つのノートブックにおける変数への値の割当てや，生成されたオブジェクトは，別のノートブック上では無効である．
ノートブックやコンソールの処理を請け負っているカーネルは，停止（Shutdown）や再起動（Restart）が可能である．この性質を利用すると，ノートブックやコンソールにある全ての入力セル In[n]: を再度実行することができる．具体的には，メニューバーの「Run」メニューの中にある「Restart Kernel And Run All Cells...」を選択する．

6.1.3

Notebook での input 関数の実行

標準入力からの入力（ユーザからのキーボード入力）を input 関数で取得することができるが，Notebook 上で input関数を使用すると Notebook 独自の GUI の形式による入力となる．

Notebook 上で input 関数を実行して，取得した文字列を表示する例を次に示す．
例．Notebook 上での input 関数の実行[*]: s = input(’ 入力してください：’)print(’ 入力結果：’+s)
入力してください：このように，入力セルの直下に input 関数のプロンプトが表示され，そのすぐ右側に入力フィールドの GUI が現れる．
ここに文字列を入力することができる．
（次の例を参照）
例．入力フィールドへの入力（続き）[*]: s = input(’ 入力してください：’)print(’ 入力結果：’+s)
入力してください： 入力した文字列
入力フィールドに入力した文字列と入力している．この直後に print 関数によってこれが表示される．
（次の例を

参照）
例．先の例の続き[6]: s = input(’ 入力してください：’)print(’ 入力結果：’+s)
[6]:

6.2

入力してください： 入力した文字列
入力結果：入力した文字列

Markdown によるコメント表示

Jupyter Notebook では，セルの書式を次の例のように Markdown にすることで，そのセル自体を Python の実行対象としない「コメント」とすることができる．

199

例．選択したセルを「Markdown」にする操作

書式を Markdown に設定したセルを評価すると「見出しセル」となる．
（次の例）

Markdown のセル内では，先頭の「#」の個数によって文書構造（章・節・項…）を表現できる．以下に例を示す．
例．Markdown セル内で「#」で記述を開始した例（続き）

例．Markdown セル内で「##」で記述を開始した例（続き）

例．Markdown セル内で「###」で記述を開始した例（続き）

200

6.3

使用例

6.3.1

MathJax による SymPy の式の整形表示

数式処理パッケージ SymPy「3.3 SymPy」は MathJax 69 の機能を利用して，Jupyter notebook 上で数式を整形表示することができる．この機能を使用するには init printing 関数によって，当該機能の使用を設定しておく必要がある．具体的にはsympy.init printing(use latex=’mathjax’)とする．SymPy の式を整形表示する例を示す．
例．モジュールの読込みと，数式整形表示の設定

例．不定積分（続き）

例．行列（続き）

例．総和（続き）

例．極限（続き）

例．導関数（続き）

69 Web ブラウザ上で数式を整形表示するための JavaScript ライブラリ．
（公式サイトは https://www.mathjax.org/）

201

6.3.2IPython.display モジュールによるサウンドの再生

IPython は JupyterLab の対話用シェルの機能を提供するものであり，IPython.display モジュールは対話シェルに関するメソッドや関数を提供する．ここでは特に● WAV 形式サウンドファイルの読込みと再生● NumPy を用いて生成した波形データ配列の再生に関する基本的な機能を紹介する．
■ モジュールの読込み

NumPy モジュールと IPython.display モジュールを読み込む例を次に示す．
例．

IPython.display モジュールを読み込んで，それを別名 ‘IPyDisp’ として扱う形にしている．これにより当該モジュー
ル配下の関数やメソッドを呼び出す際の記述を簡略化できる．
次に，WAV 形式サウンドのファイルを読み込んで再生する例を示す．まず WAV 形式ファイル’aaa.wav’ を読み込む例が次のものである．
例．WAV 形式ファイル ’aaa.wav’ の読込み（続き）

WAV 形式ファイルを読み込んで，それを Audio クラスのオブジェクト aud1 にしている．このクラスのタイプ名の確認と再生作業の例を次に示す．
例．Audio オブジェクトの型確認と再生（続き）

Audio オブジェクトの値を評価した時にこのようなインターフェースが表示される．

の部分をクリックするとサウンドが再生される．
ノートブック上でサウンド波形を合成する例を次に示す．
例．NumPy の機能を用いてサウンドを合成する例（続き）

これは 440Hz の正弦波形 sin(440 × 2π × t) を 3 秒の長さで生成した例である．サウンドをデータとして扱うには，サンプリング周波数，量子化ビット数，チャンネル数の 3 つの意識する必要がある．サンプリング周波数は r = 44100としているが，チャンネル数に関してはデータ配列の行数から自動的に決まる70 ．また，量子化ビット数も Audio オ
ブジェクト生成時に自動的に設定（16 ビット=2 バイト）される．
70 モノラルの場合は単純な一次元配列，ステレオの場合は[[右 1, 右 2,…, 右 n],[左 1, 左 2,…, 左 n]]のような形式の配列として扱う．

202

この例で生成された波形の配列オブジェクト s を再生する例を次に示す．
例．生成した正弦波形の再生（続き）

この例でもで再生できる．

203

7

その他

7.1

json：データ交換フォーマット JSON の使用

JSON（JavaScript Object Notation）は，キーと値を対応させるデータ構造の表記71 である．JSON は JavaScript
言語で使用するオブジェクトの構造に由来するが，異なるアプリケーションソフトや言語処理系の間でデータを受け渡すためのデータフォーマットとして普及している．Python にはキーと値を対応させるデータ構造である辞書（dict型）があるが，JSON と親和性が高く，Python 処理系と他のソフトウェアの間でデータの受け渡しをする際に JSONの表記に依ることが多い．

Python には JSON を扱うためのモジュールが標準的に提供されており，
import json
として読み込んで使用することができる．

7.1.1

JSON の表記

JSON では ‘[…]’ で括った配列と，‘{…}’ で括ったオブジェクトというデータ構造が表現でき，それらは Pythonのリストと辞書とほぼ同じ表記法を用いる．また JSON のデータ構造に含めることができる要素としては，数値（整数，浮動小数点数），真理値（true/false），空値（null），文字列がある．文字列の引用符にはダブルクオーテーショ
ン「”」を使用し，「￥」によるエスケープシーケンスが使用できる．真理値や空値の表記は Python のものとは異なるが，json モジュールを用いることで，JSON と Python 処理系の間で適切に変換することができる．

7.1.2

使用例

例．Python のデータ構造から JSON への変換>>> import json

←モジュールの読み込みEnter>>> d = {’ りんご’:’apple’, ’ みかん’:’orange’, ’ ぶどう’:’grape’}>>> js = json.dumps( d )>>> print( js )

Enter

Enter

←辞書を用意← dumps によって JSON に変換

Enter

←内容確認

{"￥u308a￥u3093￥u3054":"apple", "￥u307f￥u304b￥u3093":"orange",←結果表示（エスケープされた UNICODE 文字列）"￥u3076￥u3069￥u3046":"grape"}
この例のように dumps 関数によって Python のオブジェクトが JSON の表記に従った文字列に変換される．この際，多バイト文字は「￥」でエスケープされた UNICODE 列となる．JSON 表記の文字列を Python のオブジェクトに変換するには loads 関数を用いる．
（次の例参照）
例．JSON から Python のデータ構造への変換（先の例の続き）>>> json.loads( js )Enter

← loads によって JSON を Python のオブジェクトに変換{’ りんご’:’apple’, ’ みかん’:’orange’, ’ ぶどう’:’grape’}
7.1.2.1←結果表示

JSON データのファイル I/Odump 関数（dumps と混同しないように注意）を使用すると Python のデータ構造を JSON に変換したものをファイルに出力することができる．
書き方：

dump( Python のデータ構造, ファイル )例．JSON のファイルへの出力（先の例の続き）>>> f = open( ’dic01.js’, ’w’ )>>> json.dump( d, f )>>> f.close()

Enter

Enter

Enter

←ファイル ’dic01.js’ を出力モードで作成←そのファイルに辞書 d の内容を出力←ファイルを閉じる

この処理で，上の js の内容と同じものがファイル ’dic01.js’ に出力される．
71 RFC 8259

204

ファイルに保存されている JSON データを読み込むには load 関数（loads と混同しないように注意）を使用する．
書き方：

load( ファイル )読み取った JSON データを Python 形式に変換したものを返す．
例．JSON のファイルからの入力（先の例の続き）>>> f = open( ’dic01.js’, ’r’ )>>> d2 = json.load( f )>>> f.close()←そのファイルから JSON を読み込んで Python 形式に変換←ファイルを閉じる

Enter←読み取った内容を確認>>> d2{’ りんご’:7.1.2.2

Enter←ファイル ’dic01.js’ を入力モードで開くEnter’apple’, ’ みかん’:’orange’, ’ ぶどう’:’grape’}←内容表示

真理値，None の扱い（次の例参照）
空値や真理値も dumps, loads 関数で適切に変換される．
例．空値や真理値の変換（先の例の続き）>>> L = [1,2,3,None,True,False]>>> js = json.dumps( L )>>> js

Enter

Enter

Enter

←リストを用意← dumps によって JSON に変換←内容確認’[1, 2, 3, null, true, false]’>>> json.loads( js )Enter[1, 2, 3, None, True, False]←結果表示（JSON 表記の文字列になっている）← loads によって JSON を Python のオブジェクトに変換
←結果表示

205

urllib：URL に関する処理

7.2

URL の処理に関する機能を提供する urllib が Python 標準のライブラリとして利用できる．
7.2.1

他バイト文字の扱い（‘%’ エンコーディング）

URL に記述する多バイト文字（日本語など）は ‘%’ を用いた文字コードとして表記される．例えば「ウィキペディ
ア日本語版」の URL には日本語の文字列が含まれており，Web ブラウザ上での表示は‘https://ja.wikipedia.org/wiki/メインページ’となるが，これは実際には‘https://ja.wikipedia.org/wiki/%E3%83%A1%E3%82%A4%E3%83%B3%E3%83%9A%E3%83%BC%E3%82%B8’という文字列として扱われる．
多バイト文字列を文字コード列にエンコードするには urllib.parse.quote モジュールを用いる．このモジュールを読み込むにはimport urllib.parseとする．
例．他バイト文字列を文字コード列にエンコードする>>> import urllib.parse←モジュールの読込みEnter>>> e = urllib.parse.quote( ’ 日本語’ )
>>> e

Enter

Enter

←文字コード列に変換←内容確認’%E6%97%A5%E6%9C%AC%E8%AA%9E’←結果表示

文字列 ’ 日本語’ が ‘%’ 表記の文字コード列に変換されていることがわかる．このような文字コード列を元の文字列に戻す（逆変換）には urllib.parse.unquote を用いる．
例．文字コード列を他バイト文字列に戻す（先の例の続き）>>> s = urllib.parse.unquote( e )
>>> s

Enter

’ 日本語’
7.2.1.1

Enter←元の文字列に戻す

←内容確認

←結果表示

文字コード体系の指定

quote，unquote 共に，文字コード体系を明に指定する場合はキーワード引数 ‘encoding=文字コード体系’ を与える．
例．文字コード体系（shift-jis）を指定しての変換と逆変換>>> e = urllib.parse.quote( ’ 日本語’, encoding=’shift-jis’ )
Enter

←内容確認

’%93%FA%96%7B%8C%EA’

←結果表示

>>> e

>>> s = urllib.parse.unquote( e, encoding=’shift-jis’ )
>>> s

Enter

’ 日本語’

←内容確認

←結果表示

206

Enter

Enter

←文字コード列に変換←元の文字列に戻す7.3

zenhan：全角⇔半角変換

zenhan 72 は英数字や記号文字などの全角，半角を変換するためのモジュール73 である．このモジュールは使用に際して次のようにして読み込む．

import zenhan
半角文字→全角文字の変換には h2z 関数を，全角文字→半角文字の変換には z2h 関数を使用する．
例．全角，半角の変換>>> import zenhan←モジュールの読み込み

Enter

Enter

←全角文字に変換

Enter>>> z = zenhan.h2z( h )>>> z←半角文字をEnter>>> h = ’abcdABCD0123#&%’←結果の確認’ ａｂｃｄＡＢＣＤ０１２３＃＆％’←変換結果（全角）←全角文字を半角文字に変換>>> zenhan.z2h( z )Enter’abcdABCD0123#&%’←変換結果（半角）

全角⇔半角の変換機能は，次に紹介する jaconv モジュールも提供している．

7.4

jaconv:日本語文字に関する各種の変換

jaconv モジュールは日本語文字に関する様々な変換機能を提供する．jaconv に関する情報についてはインターネッ
トサイト

https://pypi.org/project/jaconv/
を参照のこと．
■ ひらがな⇔カタカナ変換
ひらがなをカタカナに変換するには hira2kata 関数を，カタカナをひらがなに変換するには kata2hira 関数を用いる．
（次の例参照）
例．ひらがな⇔カタカナ変換>>> import jaconv

Enter←モジュールの読み込み>>> s = jaconv.hira2kata(’ この文はひらがなを含んでいます．’)
>>> s

Enter

Enter

←ひらがなをカタカナに変換←内容確認’ コノ文ハヒラガナヲ含ンデイマス．’
Enter>>> jaconv.kata2hira(s)←ひらがなの部分がカタカナに変換されている←カタカナをひらがなに変換’ この文はひらがなを含んでいます．’←変換されている■ 全角⇔半角の変換
全角⇔半角変換の例を次に示す．
例．全角ひらがな→半角カタカナ（先の例の続き）>>> s = jaconv.hira2hkata(’ この文はひらがなを含んでいます．’)↑ 全角ひらがなを半角カタカナに変換
>>> s

Enter

Enter

←内容確認

’ コノ文ハヒラガナヲ含ンデイマス．’←結果表示

この例のように，全角ひらがなを半角カタカナに変換するには関数 hira2hkata を用いる．

72 https://pypi.org/project/zenhan/

73 全角，半角の変換のためのモジュールとしては，zenhan 以外にも mojimoji （https://pypi.org/project/mojimoji/）というモジュールが存在する．

207

例．半角→全角（先の例の続き）>>> jaconv.h2z(s)Enter←半角を全角に変換’ コノ文ハヒラガナヲ含ンデイマス．’←結果表示

この例のように，半角文字を全角文字に変換するには関数 h2z を用いる．また，逆の変換を行う関数 z2h も使用できる．これらの関数はカタカナを変換対象としているが，英数記号も変換対象とする場合は表 31 のようなキーワード引数を与える．
表 31: 全角⇔半角の変換対象とする文字の指定
カタカナ
数字
数字以外の ascii 文字

対象文字
キーワード引数

kana=True/False

digit=True/False

ascii=True/False
太字はデフォルト

例．全角→半角>>> jaconv.z2h(’ ａｂｃｄ１２３４＃＄％＆アイウエ’)’ ａｂｃｄ１２３４＃＄％＆アイウエ’

Enter←全角を半角に変換←カタカナのみが変換されている>>> jaconv.z2h(’ ａｂｃｄ１２３４＃＄％＆アイウエ’,digit=True,ascii=True)
対象の文字を指定して変換 ↑’abcd1234#$%&アイウエ’←変換されている

208

Enter

索引
/etc/shadow, 180

c , 64&, 69

cancel, 165

˜, 69channels, 49

＠, 123circle, 15, 31‘%’ エンコーディング, 206

clip, 153

32-bit ﬂoating-point の WAV 形式サウンドデータ, 159

Clock, 29

3 次元の散布図, 112

close, 77

3 次元の棒グラフ, 112

CMY, 5col, 172absolute, 122collect, 164

adaptiveThreshold, 11

complex128, 51

add collection3d, 147

complex192, 51

add patch, 144

complex256, 51

add subplot, 112

complex64, 51

all, 134

concatenate, 62, 63

angle, 123conj, 122

any, 134

conjugate, 127

apart, 165

convert, 24

append, 62

copy, 23, 61

arange, 55

corrcoef, 100

Arc, 145

count nonzero, 75

arc, 26

crop, 22argmax, 70, 71

CSV, 128

argmin, 70

ctypes, 186args, 163

cvtColor, 6, 10

argsort, 73

Cython, 182

array, 51
arrowedLine, 13

datetime64, 148

asarray, 140delete, 66

astype, 61

Derivative, 168

atoms, 163

destroyAllWindows, 2

Audio, 202det, 126, 173

AudioSegment, 49

diag, 125

Axes3D, 110diﬀ, 73, 167

Axes3DSubplot, 112

digest, 180

AxesSubplot, 84, 85

digitize, 94
doit, 168, 174bar, 76, 103, 120dot, 123, 125, 174

bar3d, 112

Draw, 25

barh, 103

drawMarker, 18

BGR, 5dsolve, 170

bincount, 75, 95

dtype, 52

blit, 30, 31

dump, 204

BMP, 20

duration seconds, 49

bool, 51
boxplot, 107

E, 164iEel, 45

get busy, 37

eig, 126

get fonts, 32

eigenvals, 174

get height, 30, 36

eigenvects, 174

get length, 38

Ellipse, 144

get pos, 37

ellipse, 15, 16, 26, 30

get volume, 37, 38

EPS, 20, 21

get width, 30, 36

Eq, 169

GIF, 20

evalf, 177

GRAY, 5expand, 23, 164

grid, 79

expand dims, 68Group, 42

export, 50

h2z, 207, 208

factor, 164

hashlib, 180

factorint, 175

hexdigest, 180

fadeout, 37

hira2hkata, 207

FFmpeg, 49

hist, 101

ﬀt, 118

hlines, 77

ﬀtfreq, 118

hstack, 63, 171

ﬁgsize, 121

HSV, 5, 8

Figure, 77, 84

I, 164ﬁgure, 77, 110, 121

ICNS, 20

ﬁll, 26, 124

ICO, 20

ﬁllConvexPoly, 17

identity, 124

ﬁllPoly, 16

iﬀt, 118

ﬁnfo, 54

iinfo, 54

ﬂatten, 59

IM, 20ﬂip, 60

imag, 122

ﬂoat128, 51

Image, 140

ﬂoat16, 51

image, 20

ﬂoat32, 51

Image.BICUBIC, 22

ﬂoat64, 51

Image.BILINEAR, 22

ﬂoat96, 51

Image.BOX, 22

Font, 32

Image.FLIP LEFT RIGHT, 23

font manager, 89

Image.FLIP TOP BOTTOM, 23

FontProperties, 89

Image.HAMMING, 22

format, 20

Image.LANCZOS, 22

frame rate, 49

Image.NEAREST, 22

from mp3, 49

Image.ROTATE 180, 23

from wav, 49

Image.ROTATE 270, 23

fromarray, 140

Image.ROTATE 90, 23

frombuﬀer, 133

ImageDraw, 25

full, 124

imread, 3func, 163

imshow, 2, 139gca, 86, 88

imwrite, 3gcf, 86

in32, 51

get, 2, 30

inf, 55

get array of samples, 49

info, 20ii

init, 28, 46

matplotlib, 51, 76

init printing, 201

Matrix, 171

inner, 125

matrix rank, 127

input, 199

matshow, 114

insert, 64

max, 54, 70, 71, 93

int16, 51

maximum, 151

int64, 51

MD5, 180, 181

int8, 51

merge, 7, 24

Integral, 168

meshgrid, 108, 109

integrate, 168

min, 54, 70, 93

inv, 126, 173

minimum, 151

IPython, 195, 202

mode, 20

IQR, 108

MOUSEBUTTONDOWN, 36

is プロパティ, 167

MOUSEBUTTONUP, 36

iscomplex, 122

MOUSEMOTION, 36

isﬁnite, 55

MP3, 37

isinf, 55

MSP, 20

isnan, 55nan, 55

ISO8601, 148

ndarray, 1, 51

isprime, 176

ndim, 57

isreal, 122

new, 21jaconv, 207

newaxis, 67

JPEG, 20

NINF, 55

JPEG2000, 20

norm, 127

JSON, 204

normal, 91

Jupyter, 195

NpzFile, 132

Jupyter Notebook, 195

Numba, 185

JupyterLab, 195

NumPy, 1, 51

KEYDOWN, 36

object, 51

KEYUP, 36

Ogg Vorbis, 37
ones, 124

Lab, 5, 8

oo, 164

latex, 177

open, 20legend, 77, 79

OpenCV, 1

limit, 167
linalg, 126, 127

passlib, 180

line, 13, 26, 31

paste, 23lines, 31

pause, 37

linspace, 55

pcolor, 114

load, 21, 30, 31, 37, 131, 205

PCX, 20

loadtxt, 130

percentile, 94

logspace, 56

permutation, 101
pi, 164

maen, 93

pie, 105

Markdown, 199

pieslice, 26

MathJax, 201

Pillow, 20

mathml, 177

play, 37, 38
iii

rsolve, 170

plot, 77, 178
plot3d, 178

sample width, 49

plot surface, 110

save, 21, 31, 131, 179

plot wireframe, 110

saveﬁg, 90

PNG, 20

savetxt, 128

point, 26

sawtooth, 156

PolarAxesSubplot, 87

scale, 34

Poly3DCollection, 147

scatter, 103

Polygon, 146

SciPy, 155

polygon, 26, 31

seed, 92

polylines, 16

series, 169

PPM, 20

set caption, 30

pprint, 171

set pos, 37

prime, 176

set thetagrids, 89

primepi, 176

set title, 86

primerange, 176

set visible, 87, 89

primorial, 176

set volume, 37, 38

putText, 17

set xlabel, 86, 110

PWM, 156

set xlim, 86

PyDub, 49

set xticks, 86

pygame, 28

set ylabel, 86, 110

PyInstaller, 193

set ylim, 86

pylab, 121

set yticks, 86
quantile, 94

set zlabel, 110

QUIT, 30

SGI, 20

quit, 30

SHA1, 180
SHA224, 180

r , 64

SHA256, 180

rand, 91

SHA384, 180

randint, 91

SHA512, 180

RandomState, 92

shape, 4, 56, 172

ratsimp, 166show, 22, 77

ravel, 59

shuﬄe, 101

read, 2, 159

simplify, 162real, 122

size, 20

rect, 30

solve, 169

Rectangle, 144sort, 72

rectangle, 14, 26

Sound, 38

RegularPolygon, 144

sparse matrix, 124release, 2

SPIDER, 20

render, 32

Spine, 87

reshape, 58

spines, 87, 89

resize, 4, 22

split, 7, 23, 142

rewind, 37

Sprite, 40

RGB, 4, 5

sqrt, 54, 122roll, 60

square, 155rotate, 23, 34

start, 46row, 172iv

std, 93

waitKey, 2stop, 37, 38

wave, 158

subplot, 88

WAV 形式, 158

subplots, 81

WebP, 20

subplots adjust, 82

where, 69

subs, 166

width, 26

Sum, 174

Wild, 175

sum, 93

write, 158

Surface, 28
XBM, 20

surface plot, 110

xlabel, 77, 79, 86

Surface オブジェクトのサイズ, 36

xlim, 79, 86

Symbol, 162

xticks, 80, 86

symbols, 162
sympify, 163

ylabel, 77, 79, 86

SymPy, 161ylim, 79, 86

sympy.Function, 163

yticks, 80, 86

sympy.Number, 163
sympy.Symbol, 163z2h, 207, 208

SysFont, 32

zenhan, 207
zeros, 124

T, 60, 126

zeros like, 124

table, 116
threshold, 10

アスペクト比, 121

thumbnail, 22

アニメーション GIF, 26

tich, 30

位相, 123

TIFF, 20

一様乱数, 91

tile, 64

イベントキュー, 28, 30

timedelta64, 148, 149

イベント種別, 30

title, 77, 79, 86

色空間, 4, 5

tobytes, 133

因数分解, 164transpose, 23, 126, 173

閏年, 149
エルミート共役行列, 127

uin32, 51

円グラフ, 105

uint16, 51

音声の再生, 37

uint64, 51

階級, 94

uint8, 51, 140

階差方程式, 170

unicode, 51

回転, 33

unique, 74

拡縮, 33

unpause, 37

加色混合, 4

update, 30

カテゴリデータ, 75, 129, 130

urllib, 206

加法混色, 4

urllib.parse.quote, 206

カラーバーの表示, 116

urllib.parse.unquote, 206

カラーマップ, 110関数のグラフ, 178var, 93, 162

画像モード, 20

vectorize, 135, 136

共役複素数, 122

VideoCapture, 2

共有ライブラリ, 186, 187

vlines, 77

極座標, 87

vstack, 63, 171v

鋸歯状波, 156

整列, 72近似値, 177

線形代数, 123

逆行列, 173

選言, 69行列, 123

全角⇔半角変換, 207

行列式, 173

漸化式, 170

行列のランク, 127

素因数分解, 175

区間, 94相関行列, 100

矩形波, 155

相関係数, 100

グラフの枠を非表示にする方法, 87

総和, 174

グラフを画像ファイルとして保存, 90

素数, 176

グリッド線, 79

素数階乗, 176

クリッピング, 159

ソルト, 180

グレゴリオ暦, 149

ソート, 72

減色混合, 5対角行列, 125

減法混色, 5対角成分, 125

降順, 72

対数正規分布, 97

固有値, 174

タイムスタンプ, 148

固有ベクトル, 174

タイムゾーン, 148

合計, 93

対話作業環境, 195

最小値, 70, 93

代数方程式, 169

最大値, 70, 93

遅延実行, 168

最頻値, 97

チャネル, 4

サウンドの合成, 202

チャネルの分解と合成, 7

サウンドの再生, 202

定数, 164

差分, 73

転置, 173

差分方程式, 170

デジタル署名, 180

3 次元の散布図, 112

データの整列, 72

散布図, 103

データの抽出, 68

色相, 9

統計, 93式の型, 166

頭部と引数列の取り出し, 163式の展開, 164

度数調査, 94

質的データ, 75

内積, 125, 173

指定した区間で度数を集計する, 96, 102

日本語の見出し・ラベル, 89

シャッフル, 101

ノコギリ波, 156

集計, 94ノルム, 122

振幅スペクトル, 120

ノートブック, 195

真理値, 51, 52

ハイレゾ, 158次元の拡大, 67

配列の形状, 56

数式処理システム, 161

配列の連結, 62

数値以外のデータの保存, 129

箱ひげ図, 107

数値以外のデータの読込み, 130

汎関数, 168

スカラー値の型の変換, 61

パスワードクラック, 180

ステレオサウンドの出力, 158

パスワード文字列の秘匿化, 180

スパース行列, 124

パターンマッチ, 175

スプライト, 40

ハルス幅変調, 156

スライス, 57パーセント点, 94

スライスオブジェクト, 66

ヒストグラム, 101

正規乱数, 91

否定, 69vi

標準偏差, 93
標本標準偏差, 93
標本分散, 93
ヒートマップ, 114
微分方程式, 170
フィルタ, 22
フォント名の取得, 32
複素共役行列, 127
複素数, 122
不偏標準偏差, 93
不偏分散, 93
フレームのサイズ, 4
フーリエ逆変換, 118
フーリエ変換, 118
ブロードキャスト, 53
分位点, 94
分散, 93
平均, 93平方根, 122
偏角, 123ベクトル, 123, 173
ベクトル化, 137
ベクトルのノルム, 127
方形波, 155
棒グラフ, 76, 103
ポリゴン, 146
窓関数, 121
マーカー, 18
見出し行, 130
メッセージダイジェスト, 180
面プロット, 110
要素の置換, 70
ラスタライズ, 21
量子化ビット数, 158
連言, 69連立方程式, 170
レーダーチャート, 88
ワイヤフレーム, 110

vii

謝辞
本書の内容に関して，インターネット（電子メール，SNS など）を介して多くの方々から有効な助言やリクエストをいただきました．本書の執筆と維持のために大きな貢献となっております．特に，誤った記述に対する厳しいご指摘は大変にありがたいものです．ここにお礼申し上げます．今後もご協力いただけましたら幸いです．

「Python3 ライブラリブック」− 各種ライブラリの基本的な使用方法

著者：中村勝則
発行：2022 年 3 月 25 日

本書の最新版と更新情報
本書の最新版と更新情報を，プログラミングに関する情報コミュニティ Qiita で配信しています．
→ https://qiita.com/KatsunoriNakamura/items/b465b0cf05b1b7fd4975

上記 URL の QR コード

本書はフリーソフトウェアです，著作権は保持していますが，印刷と再配布は自由にしていただいて結構です．
（内
容を改変せずにお願いします）
も受け付けています．
● 連絡先

中村勝則

内容に関して不備な点がありましたら，是非ご連絡ください．ご意見，ご要望