Jupyter 知っておくと少し便利なTIPS集

今まで仕事で使ってきた、メジャーなものからマイナーなものまで含めたJupyter NotebooksのTIPS集です。

# 入力補完

とりあえずこれが無いと生きていけません。

Nbextensions（Jupyterの拡張機能）自体が未設定であれば、一旦そちらをインストールして、その後にHinterlandという機能にチェックを入れると有効化されます。

[AnacondaのJupyter notebookでnbextensionsを使う](https://qiita.com/SaitoTsutomu/items/1326e05eb992a8aa849d)


※Nbextensionsインストール後、Jupyterのファイルリスト的な画面で、タブで「Nbextensions」という選択肢が追加されます。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/228778/b90af2bd-faee-aeaa-2dea-12b296a13b0b.png)

Azure Notebooksなどだと、最初からインストール不要で選択できるようになっています。
Google Colaboratoryなどでは、そういった設定ができるのかまだよくわかっていません。（ご存じの方コメントなどでご教示ください。）

![image.png](https://qiita-image-store.s3.amazonaws.com/0/228778/1f5b56af-0a25-7041-61c9-c7ea8703f40b.png)

Hinterland にチェックを入れたあと、もし既にノートを開いているのであればF5などすると有効化します。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/228778/e149791e-5da4-842c-0ac7-d932ec2dd78f.png)

関数などであれば、アクセス時にdocstringも表示されます。

<img width="697" alt="20180416_1.png" src="https://qiita-image-store.s3.amazonaws.com/0/228778/9469446c-c253-74e7-6ab9-301960038cdb.png">

上記みたいな、docstringが表示されている状態で、Shift押しながらTABを1回押すと、docstringの表示の高さが増えます。

<img width="692" alt="20180416_2.png" src="https://qiita-image-store.s3.amazonaws.com/0/228778/20ea517b-8c26-9541-803c-3dd0035397dc.png">

同様に、Shift押しながらTABを3回くらい押すと、画面下部にdocstringが表示されるようになります。

<img width="652" alt="20180416_3.png" src="https://qiita-image-store.s3.amazonaws.com/0/228778/f42448a3-e5a7-b40a-b384-781742330dc7.png">

docstring見ながら作業したり・・など。
また、右上のアイコンクリックなどで、別ウインドウに持っていったりすることもできます。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/228778/b6455dfe-f2f7-877f-4062-dc4b00e084a9.png)

# 目次を自動で作る

それなりにボリュームがあるノートなどでは大体使っています。

NbextensionsのTable of Contents (2)にチェックを入れて、ノートをF5などで再表示します。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/228778/4a3a200c-859d-a7c8-485e-9d7e81e75e05.png)

そうするとメニューの右の方に、ハンバーガーメニュー的なアイコンが表示されるようになるのでクリックします。

<img width="461" alt="20180416_4.png" src="https://qiita-image-store.s3.amazonaws.com/0/228778/a23e5199-9455-6474-42c2-b515f570cc02.png">

そうすると、以下のスクショの左部分のように、画面が分割されてマークダウンの見出しに応じた目次が表示されます。
マークダウンを更新すると、自動でこちらも同期されます。
それぞれリンクになっており、クリックするとその部分に飛べます。（長いノートなどで便利）

OSによってはスクショのように画面分割されておらず、ノート上に乗る形になります。その場合には、「Contents」の辺りをドラッグしてウインドウの端の方に寄せたりすると、上記のスクショのように画面を分割する形で表示したり、ノート上に乗せる形で表示したりと切り替えできます。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/228778/cb7a6a19-f2d1-0c47-e7b8-97de232d5181.png)

メニューの、「Contents [-] n **t**」みたいになっている個所の、**t**の部分をクリックすると、ノート上部に見出しを作ってくれます。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/228778/af6cc0d5-8300-87bb-b757-73cae2a75edb.png)

こちらも、マークダウンを編集すると自動で同期されます。
HTML出力してもこの見出しのリンクは残るので、共有時などにも使えます。（ただし、HTMLだと小見出しのインデントが消えます）

# 検索と置換

## ノート内検索

セル入力中の場合は、一旦Escキーを押してcommand mode（各キーボードショートカットなどが使える状態）にします。

その状態でFキーを押すと、検索と置換のダイアログを表示できます。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/228778/fb1331f2-01eb-d9b8-e8bb-afc9830220a1.png)

※基本的に↕のアイコンがクリックされていないと、循環検索にならないため、使う際は大体チェックした状態でいいと思います。

「Replace」となっている個所に入力していくと、どんな感じに置換されるのかが表示されます。（Replace Allを押すまでは置換は実行されません）

![image.png](https://qiita-image-store.s3.amazonaws.com/0/228778/1569ae80-9c9a-3f7c-08ae-d678c08c7806.png)

## 他のノートも含めた検索

IBMの拡張機能などでできるようです。なんだかんだインストールせずに過ごしてきてしまい、まだ使っていないので、詳細はリンク先をご確認ください。

> IBMが超便利な拡張機能を作ってくれたのを忘れていました。
これを入れるとjupyterからnotebookファイル内の全文検索ができます。
[データサイエンティストに向けたコーディング環境Jupyter Notebookの勧め](https://qiita.com/y__sama/items/17aedf0c05187edd61c3#jupyter-content-management-extensions)

# HTML自動保存

ノートを保存した際に、自動でHTMLが保存されるようにしておくと、共有の際に便利です。分析担当間であれば結構ノートのままチャットで展開したりすることもありますが、HTMLであれば特に環境やインストールなく共有ができます。
メニューからもHTMLが落とせるようになっていますが、そのあたりは自動化されていると快適です。

[Jupyter notebook で HTML も自動作成](https://qiita.com/junkoda/items/011d44dcc1c8bd0a936a)
私は.pyファイルまで必要なケースが少ない（そういったケースには手動でエクスポート）ので、HTML側だけ仕事で自動出力しています。

# 目に優しくする

仕事で長時間使ったりしていると、白背景だと目が辛いときがあります。そのため、メインのPCでは黒ベースのテーマを反映してあります。

custom.cssというファイルを設置することで、テーマを反映することができます。

[Jupyter Notebookを自分仕様に：背景，アイコンの変更](https://qiita.com/hiropignis/items/f2192d86971746b849e8)

最初から全部自分で設定を書いていくのは大変なので、「jupyter css theme github」などとぐぐると色々出てくるので、合ったものをベースにするといいと思います。
ただし、公開されているものだと、jupyterのバージョンの差異によるもののせいなのか、私の時には満足いく感じに一通り変更されなかったので、web開発の要領で自分でCSSを調整・追記したりして最終的に落ち着いています。
ノート用のクラス・HTML用のクラスなどでコンテナー要素の部分で結構分かれているので、それらを参照してCSSを定義すれば、ノートだけに反映する、といったこともできます。

# 部分的にスクリプトの速度を計る

ローカルで数百万行程度のデータフレームを扱う必要があり、個別にapplyなどでデータに補正を入れたりする際に、事前に書いたスクリプトの速度を確認したいことがよくあります。

マジックコマンドと呼ばれる、%を先頭に記載する方法で、%timeit と記載することで、スクリプトの処理時間などを確認できます。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/228778/abf8d9b9-0e28-5074-a708-81ed23695864.png)

```py3
%timeit 1 + 1
```

```
27.6 ns ± 4.12 ns per loop (mean ± std. dev. of 7 runs, 10000000 loops each)
```

単位は、

- ns -> ナノセカンド -> 1 / 1000 / 1000 / 1000秒
- µs -> マイクロセカンド -> 1 / 1000 / 1000秒
- ms -> ミリセカンド -> 1 / 1000秒

となります。日々、ちょっとした集計をしたりcronのコードを書いたりする際に、「これは〇〇〇万行だから、今の処理時間だとこの関数はもっとチューニングしないと集計が終わらなくなりそうだ・・」といった感じで、集計前などに使っています。

# !マークを付けると、コマンドが使える


![image.png](https://qiita-image-store.s3.amazonaws.com/0/228778/69c7bbfd-2a94-8349-535a-f258b24a107e.png)

pipコマンドなどは、結構ノート上で使うこともあります。ただし、pipでライブラリ設定などを変えた際には、ノートのカーネルを一度再起動しないと反映されません。（ノートブックサーバーなどは起動したまま行えます）

引数に、ノート上の変数を指定したい場合なとには$の記号を変数の前に置くと使えます。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/228778/525ccdca-18b8-44dd-4194-30732a4f78d2.png)


# 実は一部コマンドはそのまま実行できる

マジックコマンドや、!の記号をつけなくても、一部コマンドはそのままノート上で実行できます。

lsコマンドなど。引数も認識してくれます。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/228778/aa4ea85b-a385-54e5-3f12-710f317ff05c.png)

# ノート上でHTMLやCSS・jsなどを扱う

HTMLモジュールを使います。

```py3
from IPython.display import HTML
HTML("""
Apple
""")
```

![image.png](https://qiita-image-store.s3.amazonaws.com/0/228778/8439acc9-e9ce-2ab1-da03-c8810a39f774.png)

スタイルシートと組み合わせて、HTML要素をあとから編集したり・・

![image.png](https://qiita-image-store.s3.amazonaws.com/0/228778/73c280a6-901b-c5e5-f504-87b1bb05497b.png)

custom.cssが触れないサーバーのケースや、このノートだけスタイルを変えたい、といったケースで使える・・かもしれません。

そのほか、大分昔に無理やりGoogle Chart Toolsをノート上から扱って、データフレームを放り投げるとサンキーダイアグラムを表示してくれる・・的なことをしたこともあります。（matplotlibのものが扱いずらく、当時そういった暫定対応をしましたが、今落ち着いて振り返るとちゃんと綺麗なサンキーダイアグラムのPythonライブラリがいくつもありそうな印象・・）

## スクリプトを非表示にする

共有用には、よく「余分な部分は消しておくこと」といったことがよく言われます。（大阪ガスの方の分析の本だったり、Googleの方の本だったり）

ノートからエクセルに集計結果やグラフだけ、別途貼り付けたり、といったのもいいですが、そこまで丁寧にやらなくても相手が納得してくれる場合には、スクリプト部分を非表示にしてしまってマークダウンとグラフ表示のみ、といった具合にしてもいいかもしれません。

前述の、HTMLモジュールを応用します。（jsなどは適当）

```py3
from IPython.display import HTML

HTML("""
<button id="code-show-switch-btn">スクリプトを非表示にする</button>

<script>
var code_show = true;

function switch_display_setting() {
    var switch_btn = $("#code-show-switch-btn");
    if (code_show) {
        $("div.input").hide();
        code_show = false;
        switch_btn.text("スクリプトを表示する");
    }else {
        $("div.input").show();
        code_show = true;
        switch_btn.text("スクリプトを非表示にする");
    }
}

$("#code-show-switch-btn").click(switch_display_setting);
</script>
""")
```

ボタン押下前 :

![image.png](https://qiita-image-store.s3.amazonaws.com/0/228778/7494e32e-01a3-e928-72ac-77cb0cb57ad6.png)

押下後 :

![image.png](https://qiita-image-store.s3.amazonaws.com/0/228778/9f250015-4397-46ee-dc78-d995e3cfbe97.png)

確かノートではなくHTML出力したときにも有効になったような気がするので、共有用のHTMLでは初期表示ではスクリプト非表示にしたり、など色々応用が効きます。

# GUIを使う

ちょっとGUIがあると便利だけど、使い捨てなのでツール作るほどのことじゃない・・といったケースがあります。

ボタンだったり、スライダーだったりの基本的なUIであれば、ipywidgetsモジュールで色々用意されています。
jqueryを扱うような感覚で、ノート上でハンドラ設定などを行うことができます。

```py3
from ipywidgets import Button
from datetime import datetime

btn_A = Button(description='apple')

def on_btn_A_click(btn):
    """
    appleボタンが押された際に実行されるハンドラ。
    
    Parameters
    ----------
    btn : Button
        クリックされたボタンオブジェクト。
    """
    print(datetime.now(), "appleボタンが押されました。")

btn_A.on_click(on_btn_A_click)
btn_A
```

![image.png](https://qiita-image-store.s3.amazonaws.com/0/228778/e3dc28ae-ab3f-9b1c-1a62-1ba59cc5dd40.png)

PILライブラリと組み合わせて、やむを得ず手動でデータセットの画像の精査を行う（学習データのクラス分けを調整したり）で仕事で使ったりしたことがあります。（ノート上に画像とクラスのボタンを複数表示して、選択したら次の画像へ・・といった具合に）

他にも、インタラクティブなグラフ設定などを行う際などに便利そうです。

[ipywidgetsとbokehで『jupyter』の更なる高みへ 【インタラクティブなグラフ描画】](http://www.procrasist.com/entry/jupyter-more-interactive)

（一応、matplotlibにもインタラクティブ用の機能が色々あるようですが、癖があったので、上記のリンクのものなどの方が楽・・？かもしれません）

# 余談

- JupyterLab、まだ触っていないため、本記事では触れませんでしたが、記事読んだ感じ便利そうなので、期待です・・！
- 力尽きたので、他のマイナーなものなど省いてしまいました。機会があればまた書きたいところです。
- 他にも探せば色々出てくると思いますので、「マイナーだけどこれ便利だよ！」といったものがあれはコメントでご教示ください・・！

---

他にもPythonなどを中心に色々記事を書いています。そちらもどうぞ！
[今までに投稿した主な記事たち](https://qiita.com/simonritchie/private/992f04ef0c56914d25d2)