例題22-2:予定外だけどちょっとここでIPython Notebook

A: さて、没原稿の供養の続きである。今回はpandasをゆるーく取り上げる。

B: pandasで検索したらパンダの画像がいっぱい出てきましたよ!かわいい!

A: パッケージの名前に凝るのはいいんだけど、あまり一般的な名詞と一致しないようにしてほしいよな。検索するのが大変だ。まあ一番検索するのがうっとおしいのはR!貴様だ!

B: ぐふふっ、子パンダかわいいなあ

A: B君がそういう趣味だとは知らなかった。今日のお題は別にかわいくない方のpandasだ。調べてみた感じ 無理やり感全開な略称 じゃないみたいだな。公式ページ( http://pandas.pydata.org )にはPython Data Analysis Libraryと見出しがついている。

B: で、何が出来るんですか?

A: それなんだが、Pandasの機能を満喫するためにはIPythonをぜひ導入したいのでIPythonの話から始めよう。

B: IPython? だいぶ前の例題でやりましたよね。確か…

A: 例題10-2

B: そうそう。Aさんの趣味をひたすら聞かされる例題10。例題10を参照、で済まさないんですか?

A: うむ。当時とはもう別次元と言っていいほど変化しているのでな。B君はMathematicaを知っているか?

B: へ? 工学部の友達が初音ミク曲線とかいうのを見せてくれたソフトが確かそんな名前だったような。それが何か。

A: …その調子ではたぶん知らんだろうが、Mathematicaのノートブックというのを知っていれば例題10-2のころからのIPythonの進化を説明しやすかったのだ。

B: はあ。ノートブックですか。知りません。

A: まあ新しいIPythonを見てもらうのが一番早いだろう。Ubuntu等の人は例によってsudo apt-get install ipython-notebookとかを実行してパッケージからインストールするといい。Windowsの人は…。前回に引き続きUnofficial Windows Binaries for Python Extension Packages( http://www.lfd.uci.edu/~gohlke/pythonlibs/ )で非公式のインストーラーを入手できる。ダウンロードリストの上にも書いてある通り、pyreadlineやpyzmq、pygments、tornado、jinja2などが必要になるかも知れない。他にもmatplotlibなども必要だが、読者のみなさんはmatplotlibなんかはすでに導入済みなんじゃないかと思う。

B: Aさん、早い早い! メモが追いつかない!

A: 非公式インストーラーのダウンロードリストの上に書いてあるって言っただろ。非公式インストーラーを使わない場合はpipを使うのがいい。pip install ipythonだな。すでに古いipythonを持っている人は-Uオプションを付けて。pip install ipython -Uだね。必要なパッケージがあったらもちろん入れる。

B: もうちょっとていねいに解説しないとわかんないと思うんですが…。

A: んー。これを書いている時点で使えるPCがすでにIPythonの依存パッケージをインストール済みのやつばかりやねん。だからpip install ipythonするだけでOKなんやな。まっさらなPCを用意してる余裕が今はないので。なんならB君がまとめてくれても構わんのだぞ?

B: うぅっ、持病の癪が。

A: 頭抱えてるけど癪で痛いのは頭じゃないからな。IPythonのインストールが済んだらさっそくノートブックを開いてみよう。ユーザーのホームディレクトリなどにipython-notebookなどと適当なディレクトリを作成しておいて、そこから以下のコマンドを実行する。Windowsの人はショートカットでも作っておくといいのではないのかな。

ipython notebook --matplotlib inline

B: ショートカットってどうやって作るんですか?

A: 例えばデスクトップに作成するとするわな。デスクトップ上のアイコンなどを置いていないところで右クリックして「新規作成」で「ショートカット」を選択。出てきたダイアログの「項目の場所を入力して下さい」にC:\Python27\Scripts\ipython.exe notebook --matplotlib inlineと入力する。もちろんC:\Python27以外の場所にPythonをインストールしている人はC:\Python27の部分を適切に書き換える。

../_images/22-2-01.png

B: ふむふむ。

A: 次へ進むとショートカットの名前を聞いてくる。まあこれは自分がわかりやすい名前をつけておくといい。ここではipython notebookとしておく。

../_images/22-2-02.png

B: ipythonは全部小文字でいいんですか?

A: いいよ。ショートカットの名前だし。そもそもWindowsは大文字小文字を区別しないし。

B: ていうかそもそもLinuxでもipythonの実行コマンドは小文字ですしね。

A: だあああぁっ!そう思っとるんならつまらん突っ込みをいれるな。これでショートカット自体は完成したんだが、このままだとC:\Python27\Scriptsに作成したノートブックが保存されちゃうので、もう一工夫する。自分のユーザーディレクトリにノートブックを保存するためのフォルダを作成しておく。まあここではipython-notebookとでもしておこうか。ディレクトリを作成したら、IPythonのショートカットを右クリックしてプロパティを開き、作業フォルダーに%USERPROFILE%\ipython-notebookと入れる。

../_images/22-2-03.png

B: あっ、知ってますよ知ってますよ! %USERPROFILE%はWindowsの環境変数ですよね。環境変数USERPROFILEに設定されている値が%USERPROFILE%に展開されるのです!

A: ほう。で、USERPROFILEには何が設定されているのかね?

B: ふふふ、ログイン中のユーザーのドライブレター込みのホームディレクトリです。ログイン名がBだったら通常はC:\Users\Bです。

A: あら、てっきりまたボケるのかと思いきや正解してくるとは。B君の言うとおり、%USERPROFILE%とすると実行時にログイン中のユーザーのディレクトリ名に置き換えられる。B君の例を使うと%USERPROFILE%\ipython-notebookはC:\Users\B\ipython-notebookに置き換えられるわけだ。

B: ふふん

A: ではIPythonのノートブックを起動してみようか。さっきのコマンドを入力するなりショートカットをダブルクリックするなりすると、ブラウザが起動して以下のようなページが開く。これがIPythonのノートブックである。

../_images/22-2-04.png

B: 「このウィンドウを閉じてはいけない」ってなんですか。それにそもそもこの画面はwebブラウザのような…。どこかのwebページを開いたんですか?

A: 背後のウィンドウはIPython Notebookのサーバである。B君の言うとおり前面のウィンドウはwebブラウザだが、アドレスをよく見るとhttp://localhost:8888/treeと書いてある。localhostとはブラウザを起動しているPCそれ自身のことであり、8888はポート番号である。要するに背後のウィンドウは8888番のポートをlistenしているサーバで、このサーバにブラウザでアクセスすることによってプラットフォーム非依存のノートブック環境を実現しているのである。

B: ???

A: webブラウザは主要なOSで標準的にインストールされていて、同一のページはどのブラウザでもだいたい同じように表示されるだろ。だから複数のOS間で共通の出力やインターフェースを実現するのが簡単なんだよ。まあ「CSS3ドラえもん」の衝撃みたいなのはあったけど。

B: CSS3ドラえもん?

A: もう古いネタだけど面白いから後で検索しておきたまえ。New Notebookをクリックすると以下のような新しいタブなりウィンドウが開く。どっちが開くかはブラウザの設定次第。

../_images/22-2-05.png

A: 一番上にノートブックのタイトルが示されている。Untitled0というのがそうだね。で、普通のアプリケーションのようなメニューバーとツールバーがあって、その下に文字を入力できる欄がある。この入力欄のことをセルという。

B: Untitled0ってのがまたいかにも適当に付けました的な名前ですね。

A: ユーザーが名前を付けるのドキュメント名なんてこんなもんだろ。他にどうつけろと言うのか。でもまあ気が利かないのも確かなので、ノートブックのタイトルを変えてみよう。メニューバーからも変えられるんだが、直接Untitled0って書いてある部分をクリックすると以下のような画面に切り替わって新しい名前を入力できる。とりあえずtestとでもしておこう。

../_images/22-2-06.png

B: それこそ「適当に付けました的な気の利かない名前」のような気がしますが。

A: ほっとけ。タイトルもつけたことだし、いよいよ実際に使ってみよう。セルに、今までIPythonを使っていた時と同じようにPythonの文を入力する。途中でEnterを押せば複数行入力できる。ここではmatplotlib.pyplotとnumpyをそれぞれplt、npという名前でimportしてみよう。

../_images/22-2-07.png

A: 入力を終えたら Shiftを押しながらEnterを押す 。これでセルに入力された文がPythonで実行される。

../_images/22-2-08.png

B: お、以前のIPythonと同じように In [ ]:の中に番号が付きましたね。

A: うむ。入力した文が出力を返すものであればOut [1]:と出てくるんだが、今はimportしただけなので出力はない。続いてnumpy.linspace( )を使って0から2πまでの数列を作ろう。新しいセルにnp.linspaceと入力するんだが、IPythonのTab補完が使えることを確認しておこう。np.lまで入力してTabキーを押してみる。

../_images/22-2-09.png

B: おお、リストから選べるんですね。便利便利。えーと、「MatlabとかC++の統合開発環境みたい」。

A: こらそこ、カンニングペーパーを棒読みしない。

B: ぼくにこんなセリフをしゃべらせる作者がわるいんですよ。だいたい僕の知識の設定はどうなっているんですか。ずぶの素人になったりかなり詳しい人になったり。

A: 本当はそれぞれ別のキャラクターを用意すればいいんだろうが、ホラ。それを書き分けられるほど作者が頭良くないから。

B: ぶつぶつ。

A: ほれ、先に進むぞ。Tabで補完してもいいし自分で入力してもいいが、とにかく関数やメソッドの名前を入力した後に括弧の左側だけを入力して、ちょっと待つとこんな風にポップアップヘルプが出てくる。右上の小さいボタンを押すとポップアップを大きくしたり、ウィンドウ下部に別フレームを作ってそこでヘルプの詳細を見たりすることが出来る。×を押したりキーボードを操作したりするとポップアップヘルプは消える。

B: 「ふふん、これまた統合開発環境みたい、すごく便利そう」。

A: …。

../_images/22-2-10.png

A: とにかくnumpy.linspaceで変数tに0から2πまでの数列を作ってtに代入する。代入した後、tとだけ入力してShift+Enterを押すと、Pythonのインタプリタや以前のIPythonと同様にtの値が表示される。

../_images/22-2-11.png

A: さらにこのtを使ってリサジュー図形を描いてみる。起動時に--matplotlib inlineというオプションを付けた場合、今までのIPythonとは違ってノートブックの内部に出力される。

../_images/22-2-12.png

B: おおっ、これは新しいですね! これって入力した文とかも全部まとめてこのまんま保存できるんですか?

A: 出来る。その件は後で触れる。あれこれデータをこねくり回して分析して、手順を全部まとめて記録しておきたい時にとても便利だ。だが、あれこれデータをこねくり回すということは、結果的に分析には使わない処理が含まれてしまったりするし、セルの順番を入れ替えた方が後で読んだ時に分析の流れがわかりやすいこともある。そういう時は、メニューのEditやInsert、Cellを使ってノートブックの内容を整理すればいい。まず、CellのToggleを使って出力を全部折りたたんで、自分が入力した文をわかりやすくしてみよう。B君、メニューのCellからToggleを選んでみて。

B: Toggleなんてないんですが。

A: おっと、Current OutputとAll Outputという項目のサブメニューにToggleがある。Current Outputは現在選択中のセルのみ、All Outputはノートブック中のすべてのセルに対する操作だ。All Outputの方のToggleをやってみて。

../_images/22-2-13.png

B: ええと、こうですかね。よいしょ。

../_images/22-2-14.png

A: In [3]:は単に変数tを表示しているだけで意味がないからセルを削除しよう。In [3]:と書いてあるあたりをクリックして選択された状態にし、メニューのEditからDelete Cellを選択すると削除できる。あくまでブラウザで表示しているだけなので、右クリックしても「削除」なんてメニューは出てこないし、セルを選択してDeleteキーで削除したりできない。この辺はMathematicaな人はちょっと残念に思うかもしれない。

../_images/22-2-15.png

B: ちょっと選択されたセルの枠がわかりにくいですね。

A: そりゃそういうデザインなんだから仕方ないな。おまけにちょっと画像を縮小しているし。続いてMergeをやってみる。グラフをプロットしているセルを選択してメニューのEditからMerge Cell Aboveを選択。これで上の変数tに値を代入しているセルがくっつく。

../_images/22-2-16.png

B: くっついて何か得するんですか?

A: 一連の処理がひとつのセルにまとめられていると、「ああ、これでひとまとまりなんだ」ってわかりやすいだろ。あと、保存したノートブックを後日実行する時にも便利だ。

B: ふむふむ。

A: どんどん先に進むぞ。入力済みのセルの前後にセルを追加したい場合はInsert。入力済みのセルの順番を入れ替えたい時には、メニューのEditのCut/Copy & PasteやMove up/Move down Cellあたりを使うといいぞ。

../_images/22-2-17.png

A: そして挿入したセルに、後でノートブックを読み返して処理内容を思い出せるようにメモを入力してみる。当然、IPythonにはこれがPythonの文に見えるので、Pythonの文法にしたがって演算子などが色分けされてしまう。あんま間違えないと思うけど間違えてShift+Enterなんか押しちゃった日にゃPythonの文として実行しようとしてエラーで怒られてしまう。

../_images/22-2-18.png

B: 「演算子などが色分け」って、*とか-がマゼンタになってることを言ってるんですよね。

A: そうそう。こんな具合にコメントを入力しておきたい場合は、メニューのCellのCell TypeからCode以外の項目を選択する。ここではMarkdownにしてみよう。

../_images/22-2-19.png

B: おお、何だか知らないけど斜体になったり太字になったりしたぞ。

../_images/22-2-20.png

A: そこも注目してほしいところだけど、一番注目してほしいのはセルの左端のIn [ ]:の表示がなくなったことだな。Cell TypeをCode以外にすることによって、そのセルがPythonの文が入力されていないことをIPythonが理解できるようになったので、In [ ]:がなくなったのだ。当然、このセルを選択してShift+Enterを押しても何も実行されない。

B: ところでこの青色になったり斜体や太字になっているのはなぜですか?

A: これはMarkDownというらしい。正直私もよく知らんのだがreSTみたいなもんらしい。

B: reST?

A: reStructuredText。Pythonのドキュメントを書くときなどに使われるマークアップ言語だ。B君はHTMLは知っているんだろ?

B: 情報処理の授業でちょびっとやりましたが。

A: HTMLのもっとシンプルなやつだと思えばいい。*や-と言った記号で箇条書きや強調を指定することが出来る。

B: へえ。

A: 作成したノートブックは、そのまま保存することが出来る。メニューのFileを開くと、Save and Checkpointという項目がある。こいつを選択すると現在の状態をCheckpointとして保存して、後でRevert to Checkpointを選択すれば以前のCheckpointへ戻ることが出来る。Downloadという項目を選択すると、ノートブックをいろいろな形式でファイルに保存することが出来る。IPython NotebookというのがIPythonノートブックの保存形式で、拡張子はipynb。プロットなども全部まとめてひとつのファイルとして保存されるので便利だ。

../_images/22-2-21.png

B: Checkpointって便利そう。

A: まあ正直言うと個人的にはCheckpoint機能の使い道がいまいちよくわからんのだが…。セルの状態が完全に元に戻るわけでもないようだし、IPythonの状態が完全に戻るわけでもないようだし。Downloadの方がその時のノートブックの状態をファイルに保存するという意味ではわかりやすいような。

B: Downloadってのが違和感バリバリですけど。さっきAさんが言ってたサーバがどうとかこうとかいうのを考えるとDownloadって発想になるんですかね。

A: そうだな。あと便利なのがDownloadでPython (.py)として保存する機能。要するにPythonのスクリプトとして保存するわけだね。IPythonであれこれ試行錯誤しまくって、最終的に完成した分析スクリプトを清書するような感じに使える。

B: あとHTMLとかもあるんですね。さっきAさんが言ってたreSTも。

A: HTMLとしての保存はpandocというのがインストールされていないと使えないので注意。ついでに言っておくと印刷もpandocが必要だ。

B: pandoc?

A: pandocも 無理やり感全開な略称 じゃないっぽいね。Universal document converterということで、いろんな形式のドキュメントをいろんな形式に変換できる。例によってUbuntuとかならパッケージからインストールできるし、Windowsならインストーラーが配布されているからそいつをダウンロードしてインストールすればいい。

B: …。

A: ん?どうした?

B: URLは?

A: もう疲れたから勘弁してくれ。本来はpandasの話をするはずだったのにもうこんなにページを使っている。特に図が多いと作者が疲れて根気が続かなくなるのだ。

B: 最初の方は図に吹き出しとか入ってるのに最後の方はキャプチャしただけの図になってますしね。まあそんなこったろうと思いました。

A: そこまで察してるなら聞くなよ。Fileメニューの一番下にClose and Haltというのがあるが、こいつを選択するとIPythonのカーネルを終了してノートブックを閉じて、最初の画面に戻る。

../_images/22-2-22.png

B: また開きたい時はtest.ipynbというやつをクリックすればいいんですか?

A: その通り。削除したい時は右端のDeleteをクリックする。ちなみに他のタブでノートブックを開いて作業している場合はDeleteではなくShutdownというボタンが表示されている。ノートブックを削除する前にまずカーネルをシャットダウンしろということだね。ShutdownするとボタンがDeleteになる。

B: さっきから出てくるカーネルという言葉が気になるんですが…。

A: んー、正確に説明するのは難しいけど、要するに、ノートブックをひとつを開くたびに、そのノートブック用のPythonインタプリタがひとつ実行されると思ったらいい。このPythonインタプリタがカーネルで、ノートブックでShift+Enterを押すとそのセルの内容がカーネルに送られて処理が行われる。処理が済んだらカーネルは結果をノートブックに返し、ノートブック上に表示される。

B: じゃあカーネルをシャットダウンしたら、ノートブックをいくら操作しても何も起こらないってことですか?

A: カーネルが必要な処理は、な。セルの削除とかCell Typeの変更とかはカーネルを必要としないので操作できる。Shift+EnterでPythonの文を評価させることはB君の言うとおり出来ない。

B: うーん、ややこしいなあ。

A: シャットダウンしたノートブックを操作するなんていうややこしいことをB君が言い出すから悪いんだろ

B: てへへ。

A: さて、まだまだ解説しようと思えば話題はあるけど、このくらいで終わりにしておこう。pandasの話をするつもりだったのだがすっかり長くなってしまったから、pandasの話は例題22-3としようか。ページ構成上はここで区切るけど、話は続けてするからB君はまだ付き合うように。

B: (IPythonをちまちまいじりながら)へーい。

A: それでは例題22-2はこれにて…

B: っと、ちょっと待ってください!

A: おしまい、ってなんだよ出し抜けに。

B: これってどうやって保存するんですか? あ、これってグラフのことですが。右クリックしてもあまり画質の良くないのPNGファイルとしてしか保存できないようなんですが。

A: ん? 普通のブラウザの画像なんだから当然だな。IPythonノートブックをinlineオプションを付けずに(ipython notebook --matplotlib)起動すると、従来のIPythonならプロットが別ウィンドウで開くので、そのウィンドウのツールバーからファイル形式を指定して保存することが出来る。

../_images/22-2-23.png

B: えーっ、これじゃ格好よくな…じゃない、せっかくグラフもまとめて保存できるノートブックが台無しじゃないですかー。

A: む。それは確かに。そういう場合は仕方ないからsavefigを使うしかないかなあ。…って、あれ?savefigで保存されたグラフが真っ白だぞ?

B: どうかしましたか?

A: あれ? あれ? これならどうだ、そりゃ!

B: …。

A: ふむ。同じセルにないといけないんだな。たぶん。

B: 一人で納得していないで教えてくださいよ。

A: おう。いや、B君の質問も役に立ったというかなんというか。ちょっとこれは軽くハマりそうな落とし穴な気がする。ipython notebook --matplotlib inlineでグラフをノートブックに埋め込んでいる場合、savefigを使って図をファイルに出力するにはplotとsavefigが同一のセルになければならない。たぶん。

B:

A: 下図の左のように、まずプロットして「ふむ、この図がいい感じだから保存しよう」と思ってからおもむろに次のセルでsavefigをすると、空っぽのグラフが出力されてしまうのだよ。そうではなくて、「この図を保存しよう」と思ったら、下図右のようにグラフをプロットした文が書いてあるセルにsavefigを付け加えてもうセルを実行しないといけないのだ。

../_images/22-2-24.png

B: 気を付ければなんとかなりそうですが、最初は戸惑いそうですね。

A: ブラウザで表示を行っていることの限界かな。まあこの業界は進歩が速いから数年後には普通にグラフを右クリックして保存形式を選択して保存できるようになっているのかもしれない。

B: この「Pythonで心理実験」もそんなのばっかりですしね。PsychoPyなんか…ふぐぁ?!(飛んできた謎の針のような物体が刺さって倒れる)

A: ふっ、消されたか。作者をいじるのもほどほどにしておけとあれほど言ったのに。さて、B君がいないとなるとpandasの解説はどうするかな?