カテゴリ:Python( 15 )

ipython --pylab

ipython に --pylab コマンドラインオプションをつけて起動してみた。こうすると、次の例のように円周率の pi や linspace 関数や plot 関数や畳み込み関数の convolve など数学関連の関数がモジュール指定なしに動作しているようだ。数学の教科書を読むときに便利かもしれない。

C:\Users\******>ipython --pylab
Python 3.6.4 (v3.6.4:d48eceb, Dec 19 2017, 06:54:40) [MSC v.1900 64 bit (AMD64)]

Type 'copyright', 'credits' or 'license' for more information
IPython 6.2.1 -- An enhanced Interactive Python. Type '?' for help.
Using matplotlib backend: TkAgg

In [1]: x = linspace(0,6*pi)

In [2]: y = sin(x)

In [3]: z = sin(2*x)

In [4]: a = exp(-0.25*x)

In [5]: plot(x,y)
Out[5]: [<matplotlib.lines.Line2D at 0x2498e0042b0>]

In [6]: plot(x,z)
Out[6]: [<matplotlib.lines.Line2D at 0x2498e071668>]

In [7]: plot(x,a)
Out[7]: [<matplotlib.lines.Line2D at 0x2498e06f780>]

In [8]: plot(x,convolve(a,y)[0:50])
Out[8]: [<matplotlib.lines.Line2D at 0x2498e07ffd0>]

In [9]: plot(x,convolve(a,z)[0:50])
Out[9]: [<matplotlib.lines.Line2D at 0x2498e085a20>]

In [10]: close()

インパルス応答関数が指数関数のCR回路に正弦波を入力すると、高周波のほうが振幅が小さくなることが分かる。

上の実行例でグラフが記述できるのだが、ipython の使い方のメモということで画像は添付していません。使い方が分かるようになるためには、こういう単純な例を繰り返し実行させて手になじませる必要があるようだ。


[PR]
by tnomura9 | 2018-04-18 12:57 | Python | Comments(0)

Python によるデータ分析入門

『Pythonによるデータ分析入門』Wes Machinney 著を一通り通読した。この本は一体どういう本なのだろうか。それは、巻末の著者紹介を読めばわかる。以下に引用する。

著者紹介
Wes McKinney (ウェス・マッキニー)
ニューヨークを拠点に活動するデータハッカー兼起業家。MITで数学を専攻し、2007年に卒業した後は、コネチカット州グリニッジのAQR Capital Management でクオンツ運用に従事。使いにくいデータ分析ツールに辟易し、2008年に Python を覚えて、のちに pandas と呼ばれることになるプロジェクトを始める。現在 Python の科学コミュニティーのアクティブメンバーであり、データ分析、金融、統計計算アプリケーション部門での Python 推進者でもある。

つまり、この本は金融関係のデータマイニングに Python を使う人のための本だ。それ以外には、数値データを統計処理する研究者にも有用だろう。管理人は残念ながらそのどれにも該当しない。

この本は pandas を使いこなせるようになるための教科書だ。ただ、pandas というライブラリの使い方を学ぶだけでは使えるようにはならないようだ。pandas を使いこなせるようになるためには IPython、Numpy 、matplotlib などのライブラリの知識も必要だ。これらのライブラリが有機的に pandas と組み合わされることによって。数値データの統計的な分析を効率的に行うことができる。

この本では、Ipython、Numpy、pandas、matplotlib という4つの Python のモジュールが有機的に解説されていて、pandas を用いたデータ分析が実践的に行えるようなるように構成されている。

Python で金融データの処理や、統計計算をしてみたいと思う人にはお勧めの一冊ではないだろうか。また、AI を使ってみたいと思って Python を学ぶ人にも必読の書だろう。

しかし、単に Python を使ってみるという目的のためにもこの本は示唆的だ。まず、IPython は、Python を対話的に使うだけでなく、シェルとしても使うことができるのが分かる。IPython 上でデータを扱うためのファイル操作を含めてすべてを行えるのだ。Numby は ndarray という多次元の数値データ型を提供し、複数の数値データを全くループを書くことなく自由に加工することが可能になっている。また、matplotlib を使うことによってこれらのデータを簡単に図表化することによって数値データの可視化を行える。pandas は Excel に似た表計算のデータを Python で簡単に処理するためのモジュールだ。pandas の最大の利点は欠落データのある数値データを簡単に取り扱えることだろう。実世界のデータを扱うときに欠落データの処理は必発だ。

対話的な環境で、複雑なデータをオブジェクトにくるんで、ループなどの制御構造なしにリアルタイムに処理するというスキーマは Python 以外のプログラム言語を使う際にも共通する重要な戦略になるような気がする。

[PR]
by tnomura9 | 2018-04-11 22:11 | Python | Comments(0)

Python と JSON

Python では json モジュールをインポートすると、簡単に JSON のデータを Python のオブジェクトに変換できる。これをテストするのに自分で JSON データを作るのは面倒だし、面白くないのでオープンデータを利用してみた。次のサイトでは無料で API を使って鉄道路線に関する JSON データを利用することができる。


HeatRails Express のホームページの API タグをクリックすると路線データを取得するための API の説明が記載してある。今回は単に JSON データが欲しいだけなので、「駅情報取得 API」のサンプルレスポンスの「新宿」に合致する駅の情報の一覧のクエリのリンクを右クリックして JSON ファイル json.json をダウンロードした。ファイル名は sinjuku.json に変更した。

Windows のスタートメニューから [Anaconda3 (64-bit)] - [Anaconda Prompt] を選択。ダウンロードした sinjuku.json のあるディレクトリに移動し、ipython を起動した。

まずファイルのデータを文字列 sinjuku_file に取り込む。
In [1]: sinjuku_file = オープン('sinjuku.json','rt',encoding='utf-8').リード()

*オープンとリードは実際には英小文字で入力

json モジュールをインポートし、
In [2]: import json

文字列をオブジェクトの sinjuku に変換する。
In [3]: sinjuku = json.loads(sinjuku_file)

sinjuku オブジェクトの内容は次のようになる。
In [4]: sinjuku
Out[4]:
{'response': {'station': [{'line': 'JR中央線',
'name': '新宿',
'next': '大久保',
'postal': '1600022',
'prefecture': '東京都',
'prev': '代々木',
'x': 139.700464,
'y': 35.689729},
{'line': 'JR埼京線',
'name': '新宿',
'next': '池袋',
'postal': '1600022',
'prefecture': '東京都',
'prev': '渋谷',
'x': 139.700464,
'y': 35.689729},
.....

response と station のキーは不要なので取り除くと検索結果のオブジェクトのリストが得られる。
In [5]: sinjuku = sinjuku['response']['station']

このリストから内包表記で路線と前後の駅のタプルのリストを作る。
In [6]: [(stn['line'],stn['prev'],stn['next']) for stn in sinjuku]
Out[6]:
[('JR中央線', '代々木', '大久保'),
('JR埼京線', '渋谷', '池袋'),
('JR山手線', '代々木', '新大久保'),
('JR湘南新宿ライン', '池袋', '渋谷'),
('JR総武線', '大久保', '代々木'),
('京王線', None, '笹塚'),
('小田急小田原線', None, '南新宿'),
('東京メトロ丸ノ内線', '新宿三丁目', '西新宿'),
('都営大江戸線', '代々木', '都庁前'),
('都営新宿線', None, '新宿三丁目')]

JSON データをオブジェクトに変換するのも、オブジェクトの処理も簡単だった。

[PR]
by tnomura9 | 2018-03-27 07:53 | Python | Comments(0)

jupyter notebook

Anaconda をインストールしたら、Python の対話環境である jupyter notebook を使うことができる。これはブラウザで Python のコードを入力し、実行、保存ができるようになっている。

起動はスタートメニューから [Anaconda3 (64-bit)] - [Jupyter Notebook] を選択する。ウェブベースのアプリケーションなのでウェブサーバーが立ち上がるまでしばらく待たされるが、やがて、ウェブのページが自動的に表示される。

これはエクスプローラと操作が似ている。フォルダーの名称をクリックするとそのフォルダーが開く。新しいフォルダーはツールバーの [New] ドロップダウンリストから Folder を選ぶ。フォルダーの名称は最初 Untitled になっているが、フォルダーのチェックボックスをクリックすると、ツールバーに Rename ボタンが現れるのでそれをクリックするとフォルダーの名称変更ができる。フォルダーの削除はゴミ箱アイコンをクリックする。

Python のコードを保存したいフォルダーを開いたら、ツールボックスの [New] ドロップダウンリストをクリックし Python 3 を選択すると、新しいノートブックが表示される。ノートブックのメニューバーの Help リストの User Interface Tour を選択すると notebook の各種のコントロールの簡単な説明を見ることができる。

Notebook のコード表示エリアには最初テキストボックスが一つしか表示されていないが、そこをクリックすると Python のコードを入力することができる。まず、

print('hello, world')

と入力してリターンキーを押すと、カーソルが次の行に移動するだけでコードは実行されない。これは入力が複数行のものも作成するためである。

テキストエリアのコードを実行するにはツールバーの [Run] ボタンをクリックするか、Ctrl-Enter と入力する。コードの実行結果はテキストボックスの下に表示される。入力したコードとその実行結果はひとかたまりで「セル」と呼ばれる。Shift-Enter のショートカットでもコードを実行できるが、コードが実行された後そのセルの下に新しいセルが作成される。

このように一つの notebook には複数のセルを作成できるので、複数のスニペットを一つの notebook で管理することができる。これらのセルはファイルとして保存できる。ツールバーのフロッピーディスクアイコンをクリックするといい。ノートブックの名称変更は Jupyter タイトルの横に表示されているノートブック名をクリックすると変更できる。

ノートブックを終了するときは File メニューの Close and Halt を選択すると、自動的にノートブックのタブも消滅する。フォルダーの表示に戻ると、そこにノートブックのファイルが、.ipynb の拡張子で表示されている。ファイル名をクリックするとノートブックを再び表示させることができる。

セルには Python のコードだけではなく、マークダウンによる文書を記述することができる。セルのタイプをマークダウンに変更するには Cell メニューから [Cell Type] - [Markdown] を選択する。マークダウンで入力した後コード実行と同じように Ctrl-Enter をおすとレンダリングして表示される。再編集はセルを選択し Enter キーをおす。

Jupyter notebook を触ってみた感想は、スニペットの管理には使いやすいかなという感じだ。

ちなみに木星は Jupiter で Jupyter ではない。Google 検索で使い方を検索するときに木星の情報が出てこないので便利だ。

ノートブックの本体はファイルのチェックボックスをチェックした後、ツールバーの [Edit] ボタンをクリックすると見ることができる。驚いたことにこれは普通の JSON のテキストファイルだ。Python の対話型環境の使いやすさはもちろんだが、Web アプリケーションのお手本になるかもしれない。

参考サイト




[PR]
by tnomura9 | 2018-03-25 00:11 | Python | Comments(0)

Anaconda をインストールした。

『入門 Python 3』を一通り読み終わったので、いよいよ機械学習の勉強を始めようと思って『ゼロから作る Deep Learning』を読み始めたらいきなり NumPy や matplotlib などの外部モジュールが必要だった。Windows の Python では pip もついていないようなので、Windows では機械学習の勉強は無理かとがっかりしていたら、Window 用の Anaconda をインストールすればいいのが分かった。


インストール後に、『ゼロから作る Deep Learning』の次の例を実行してみたら、サインカーブが描画された。

import numpy as np
import matplotlib.pyplot as plt

x = np.arange(0, 6, 0.1)
y = np.sin(x)

plt.plot(x, y)
plt.show()

Anaconda には必要なものが全部揃っているようだ。まさに、"batteries are included" だった。

追記

ユーザのディレクトリ名が日本語だとインストールできなかった。ascii 文字列のローカルアカウントを新しく作ったらそちらにはインストールできた。


[PR]
by tnomura9 | 2018-03-19 08:04 | Python | Comments(0)

Python でシーザー暗号

以前に Haskell でシーザー暗号を作ってみたが、Python でもできるのではないかと思ってやってみた。

>>> chars = [chr(x) for x in range(97,97+26)]
>>> chars
['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', '
'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z']
>>> rotate = lambda n,xs: xs[n:] + xs[:n]
>>> rotate(3, chars)
['d', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', '
't', 'u', 'v', 'w', 'x', 'y', 'z', 'a', 'b', 'c']
>>> code = rotate(3, chars)
>>> code
['d', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', '
't', 'u', 'v', 'w', 'x', 'y', 'z', 'a', 'b', 'c']
>>> encoder = dict(zip(chars, code))
>>> encoder['c']
'f'
>>> decoder = dict(zip(code, chars))
>>> decoder['f']
'c'
>>> encode = lambda xs: ''.join([encoder[x] for x in xs])
>>> encode('hello')
'khoor'
>>> decode = lambda xs: ''.join([decoder[x] for x in xs])
>>> decode('khoor')
'hello'

上の例はコンソール上で関数チェックをしながらの操作だが、プログラムだけを抜き出すと次のようになる。

>>> chars = [chr(x) for x in range(97,97+26)]
>>> rotate = lambda n,xs: xs[n:] + xs[:n]
>>> code = rotate(3, chars)
>>> encoder = dict(zip(chars, code))
>>> decoder = dict(zip(code, chars))
>>> encode = lambda xs: ''.join([encoder[x] for x in xs])
>>> decode = lambda xs: ''.join([decoder[x] for x in xs])

あまり Python らしくないプログラムかもしれないが、それでもきちんと動くプログラムだ。逆に言うと、リストの内包的定義や、λ記法や、関数オブジェクトを自然に仕様の中に取り込んでいることが分かる。

[PR]
by tnomura9 | 2018-01-22 18:12 | Python | Comments(0)

Python datetime モジュール

Pythonの datetime モジュールを使ってみた。今日の日付と曜日を調べた。

>>> from datetime import date
>>> today = date.today()
>>> today.isoformat()
'2018-01-12'
>>> today.year
2018
>>> today.month
1
>>> today.day
12
>>> today.weekday()
4
>>> weekday = 'Monday,Tuesday,Wednesday,Thursday,Friday,Saturday,Sunday'.split(',')
>>> weekday
['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday', 'Sunday']
>>> weekday[today.weekday()]
'Friday'

ついでに安室奈美恵の生まれた日の曜日を求めた。

>>> amuro = date(1977,9,20)
>>> weekday[amuro.weekday()]
'Tuesday'

Python 言語の基本的な使い方が分かったら、あとは標準や非標準のモジュールを調べて、問題解決に使う必要がある。しかし、そのためにはプログラミングで解決すべき問題がなければならない。さしあたって解決したい問題がないというのがアマチュアプログラマの弱点だ。

自分が何をやりたいのか。それを解決するためのプログラミング言語以外の知識を持ち合わせているか。そちらのほうを明確にするのが必要なのだ。

[PR]
by tnomura9 | 2018-01-12 12:54 | Python | Comments(0)

Python で木構造を扱う

関数型言語でよく使われるデータ構造にはリスト型以外に木構造がある。Haskell の場合には木構造は代数的データ型で定義する。例えば次のようにノードには左右の木構造を収め、リーフに文字列を収めるデータ構造 Tree を定義する。

Prelude> data Tree = Node Tree Tree | Leaf String deriving Show
Prelude> let a = Node (Leaf "hello") (Node (Leaf "world") (Leaf "."))

この木構造のリーフの値を列挙する go_around 関数は次のように再帰的に定義できる。

Prelude> :{
Prelude| let
Prelude| go_around (Leaf str) = [str]
Prelude| go_around (Node left right) = go_around(left) ++ go_around(right)
Prelude| :}
Prelude> go_around a
["hello","world","."]

Python で木構造を定義するには、ノードとリーフのデータ型をクラスで定義する。Haskell で代数的データ型で定義したところを、Python ではクラスを定義することで木構造のデータ型を作ることになる。代数的データ型のデータがクラスのインスタンスに相当するわけだ。こう考えると、クラスの定義の、新しいデータ型を定義するという一面が明らかになる。あるいは、オブジェクト指向言語のクラスの性質の一部は Haskell の代数的データ型として捉えることができることが分かる。

class Node:
    def __init__(self,left,right):
        self.left = left
        self.right = right

class Leaf:
    def __init__(self,data):
        self.data = data
    def get(self):
        return self.data
def go_around(tree):
    if isinstance(tree, Leaf):
        return [tree.get()]
    else:
        return go_around(tree.left) + go_around(tree.right)

a = Node(Leaf('hello'), Node(Leaf(','), Leaf('world')))
print(go_around(a))

実行例

================== RESTART: C:/Users/****/Desktop/tree.py ==================
['hello', ',', 'world']

このように、Haskell の代数的データ型とPythonのクラス定義の意味合いが同じ事が分かる。どんなプログラム言語であれ、プログラムをデータ構造とアルゴリズムとして捉えるとそれらのプログラム言語の本質をとらえて活用できるような気がする。データ構造とアルゴリズムへのアプローチの仕方に言語の特徴がみられるだけだからだ。
Python という言語の使い方がなんとなくわかった気がするので Python 関係の記事はこれで終わりにする。AI との関連性についてはもう少し沈黙して勉強しないといけない。


[PR]
by tnomura9 | 2018-01-08 15:49 | Python | Comments(0)

list.pop()

Python のリスト型のメソッドの list.pop() と list.append() を使うとスタックが実装できる。スタックを使ったプログラムの例として逆ポーランド記法で記述した整数の電卓を作ってみた。コマンドラインから逆ポーランド記法でスペース区切りで数式を入力すると計算をしてくれる。数値のスタックが動的にどのように推移していくかを見ることができる。

実行例

input expression: 1 2 + 3 *
[1]
[1, 2]
[3]
[3, 3]
[9]
9

プログラム(IDLEを使って作ったが、シェルからも動かせるはず。)

value_stack = []
stack = []

def calc(stack):
    for acc in stack:
        if acc.isdigit():
            value_stack.append(int(acc))
        elif acc == '+':
            a = value_stack.pop()
            b = value_stack.pop()
            value_stack.append(a+b)
        elif acc == '*':
            a = value_stack.pop()
            b = value_stack.pop()
            value_stack.append(a*b)
        print(value_stack)

while True:
    line = input('input expression: ')
    if line == 'quit': break
    stack = line.split(' ')
    calc(stack)
    print(value_stack.pop())


[PR]
by tnomura9 | 2018-01-07 19:04 | Python | Comments(0)

reduce()

Python 3.6 の組み込み関数からは reduce() が削除されていたので作ってみた。

>>> def reduce(f,x,xs):
...     for y in xs:
...         x = f(x,y)
...     return x
...
>>> reduce(lambda x,y: x+y, 0, [1,2,3,4,5])
15
>>> reduce(lambda x,y: x*y, 1, [1,2,3,4,5])
120

これは Haskell の foldl に相当する。f(x,y) = x+y, x =0, xs = [1,2,3,4,5] の場合この関数は次のような計算になる。

reduce(f,0,[1,2,3,4,5]) = (((((0+1)+2)+3)+4)+5)

つまり、リスト [1,2,3,4,5] の要素を先頭からアキュームレータ x に加算していく。Haskell の場合は変数への再代入ができないので、右項の計算式を展開していってリストの最後まで展開していった時点で式の計算を行っている。Python のような手続き型言語は、変数への再代入が可能なので明示的に x をアキュームレータにしてループを回すことで計算できる。

Haskell のリスト関連の関数で、foldr, foldl は難解なほうだが、手続き型の言語と比較することで、その意味がよくわかる。

reduce と foldl のような等価な動作をする関数を関数型と手続き型とで対比することによって、それぞれのコードの意味がよくわかるのが面白い。

[PR]
by tnomura9 | 2018-01-06 19:12 | Python | Comments(0)