%%HTML
<link rel="stylesheet" type="text/css" href="./static/css/custom.css">
<link rel="stylesheet" type="text/css" href="./static/css/highlight.css">
%matplotlib inline
%load_ext tsumiki
import datetime
import this
import time
from io import StringIO
import matplotlib.pyplot as plt
import numpy as np
import pandas as pd
from IPython import display
from ipywidgets import FloatSlider, IntSlider, interact
from jinja2 import Template
%%tsumiki
:Markdown:
### 共著
:Markdown::
#### PythonユーザのためのJupyter[実践]入門
* Jupyterのつかいかた
* pandasの基礎
* データの可視化
**Matplotlibの豆腐で困ってる人は本書を読むように!**
* クラウド上のJupyter
* R, RubyでJupyter
* スライド, ipywidgetsなど
:HTML::
<img src="./static/images/jupyterbook.jpg" width=300 />
%%tsumiki
:Markdown:
### Software Design 2018年2月号に寄稿
:Markdown::
第1特集「そのPythonライブラリ,どうして必要なんですか?」
* 第1章:パッケージ管理の基礎を知ろう
効率的な開発のための前準備……石本 敦夫
* 第2章:Pythonの基礎力を高めよう
ライブラリの使い方と作り方……くーむ
* 第3章:データ分析の前処理をさくっと終わらせよう
定時に帰るためのpandas入門……@driller
* 第4章:イメージどおりにデータを可視化しよう
データに隠された意味を見つけるMatplotlib入門……片柳 薫子
:HTML::
<img src="./static/images/sd201802.png" width=300 >
%%tsumiki
:Markdown:
### fin-py
:Markdown::
* Python x 金融のコミュニティ
* PyConJP 2016をきっかけに発足
* もくもく会(月例)
* トークイベント(不定期)
* スピンオフイベント(オプション勉強会など)
:HTML::
<img src="./static/images/finpy_600x600.png" width=300 />
%%tsumiki
:Markdown:
#### Agenda
:Markdown::
* Project Jupyter
Jupyterの歴史
* Jupyter Notebookの基本
基本を押さえて効率的に
* マジックコマンド
便利なコマンド集
* Unofficial Jupyter Notebook Extensions(nbextensions)
拡張機能で更に便利に
:Markdown::
* IPython.display
出力をカスタマイズ
* ipywidgets
インタラクティブに
* Jupyter Notebookでプレゼンテーション
資料作成を効率的に
* Jupyter Publishing
技術的な文書・WebサイトもJupyterで
* 便利なライブラリ・Webアプリケーション
更にJupyterを使いこなす
%%tsumiki
:Markdown::
### Project Jupyter
* 2014 - Fernando Pérez氏がIPythonからスピンオフしたJupyterプロジェクトを発表
* 名称は **Ju**lia **Py**thon **R** から
* 2018年9月時点では数十のコンピュータ言語に対応
:HTML::
<img src="./static/images/jupyter-logo.svg" width=300/>
User Interfaces | IPython | Kernels | Widgets |
---|---|---|---|
JupyterLab | IPython | IPython | IPyWidgets/Jupyter Widgets |
Jupyter Notebook | IPyParallel | IRkernel | widget-cookiecutter |
Jupyter Console | Traitlets | IJulia | - |
Qt Console | - | Community maintained kernels | - |
Notebook Documents | JupyterHub | Deployment | Foundations |
---|---|---|---|
nbconvert | JupyterHub | Docker Stacks | Jupyter Client |
nbformat | Zero to JupyterHub | Kernel Gateway | Jupyter Core |
nbviewer | nbgrader | - | Jupyter Alabaster Theme |
- | All JupyterHub Projects... | - | - |
%sc -l out=vmstat 1 5
out.l
df = pd.DataFrame(out.fields()[2:], columns=out.fields()[1], dtype=float)
df
df.loc[:, "si":].plot(figsize=(12, 6));
%sc -l out=vmstat 1 5
df = pd.DataFrame(out.fields()[2:], columns=out.fields()[1], dtype=float)
df.loc[:, "si":].plot(figsize=(12, 6));
Docstringを確認できる
ソースコードを確認できる
オブジェクトをワイルドカードで検索できる
%%tsumiki
:Markdown::
#### `_`, `__`, `___` (アンダースコア)
`_`: 直前の **実行結果**
`__`: 2つ前の **実行結果**
`___`: 3つ前の **実行結果**
<p>
実行した順番 ≠ セルの順番
</p>
:Markdown::

%%tsumiki
:Markdown::
#### `_番号`
`_1`: セル番号1の実行結果
`_2`: セル番号2の実行結果
`_3`: セル番号3の実行結果
:Markdown::

%%tsumiki
:Markdown::
#### `_i`, `_ii`, `_iii`
`_i`: 直前に **実行した** 入力
`_ii`: 2つ前に **実行した** 入力
`_iii`: 3つ前に **実行した** 入力
<p>
実行した順番 ≠ セルの順番
</p>
:Markdown::

%%tsumiki
:Markdown::
#### `_i1`, `_i2`, `_i3`
`_i1`: セル番号1の入力
`_i2`: セル番号2の入力
`_i3`: セル番号3の入力
:Markdown::

%%tsumiki
:Markdown::
#### `_dh`, `_oh`
`_dh`: Notebookのカレントディレクトリ
`_oh`: セル番号と実行結果の辞書
`_ih`: **入力した順番** リスト
:Markdown::

print(1)
_
,
を取り除くdata = pd.Series(['1000', '2,000', np.nan, '4,000'])
data
別オブジェクトに格納していく
do_something1 = data.method()
do_something2 = do_something1.method()
do_something3 = do_something2.method()
,
を取り除く
_.str.replace(",", "")
型変換する
_.astype(float)
線形補間する
_.interpolate()
"".join((_iii, _ii, _i)).replace("_", "")
# このような書き方も
# "".join(_ih[start:end]).replace("_", "")
!
を行頭につけるとOSのコマンドが実行できる!!
上記の機能に加え、結果をリストに格納できる!ls sample
!cat sample/file1.csv
!!cat sample/file1.csv
%%tsumiki
:Markdown:
### OSコマンド関連
:Markdown::
#### ディレクトリ
* %cd, %pwd,
#### ファイル・ディレクトリ操作
* %cp, %mv, %rm, %rmdir
#### ls
* %ldir, %lf, %lk, %ll, %ls, %lx
:Markdown::
#### ファイルの内容
* %cat, %less, %more
#### man
* %man
#### 環境変数
* %env, %set_env
!
で代用できるコマンドだがOS依存がなくなるls
やpwd
が気軽にできる!__name__
などの特殊なオブジェクトは出てこないi = 1
s = "a"
%whos
!!
と等価-l
:結果をリストに格納-s
:空白文字をセパレータとして処理%%writefile sample/hello.py
def func():
return "hello world"
from sample import hello
hello.func()
%time
, %timeit
をセル全体に対して実行できる
!!
, %system
, %sx
をセル全体に対して実行できる
%%sx
cat sample/file1.csv
echo
cat sample/file2.csv
標準出力と標準エラーをオブジェクトに格納できる
%%capture capture_out
print(1)
capture_out.stdout
bashを実行する
%%bash
for file in sample/*.csv
do
grep 1 $file
done
python2のコードを実行する
%%python2
def func():
yield 1
func().next()
print range(3)
pypy3
ではなくpypy
を呼び出すpypy3
にする場合には環境変数やPATHを工夫するimport time
start = time.time()
for x in range(1000000):
x ** 2
print(time.time() - start)
%%pypy
import time
start = time.time()
for x in range(1000000):
x ** 2
print(time.time() - start)
実行速度が70倍に!
JavaScriptのコードを実行
%%javascript
function fizzbuzz(n) {
if (n % 3 == 0 && n % 5 == 0) return "Fizz,Buzz";
else if (n % 3 == 0) return "Fizz";
else if (n % 5 == 0) return "Buzz";
else return n;
}
console.log(element.text(fizzbuzz(5)))
Rubyのコードを実行
%%ruby
def fizzbuzz(n)
if n%15==0
return "FizzBuzz"
elsif n%3==0
return "Fizz"
elsif n%5==0
return "Buzz"
else
return n
end
end
puts fizzbuzz(3)
Perlのコードを実行
%%perl
sub fizzbuzz {
my ($n) = @_;
if ( $n % 3 == 0 && $n % 5 == 0 ) {
return "Fizz,Buzz";
}
elsif ( $n % 3 == 0 ) {
print "Fizz";
}
elsif ( $n % 5 == 0 ) {
return "Buzz";
}
else {
return $n;
}
}
print fizzbuzz(15)
%%script julia
function fizzbuzz(n)
if n % 15 == 0
println("fizzbuzz")
elseif n % 5 == 0
println("buzz")
elseif n % 3 == 0
println("fizz")
else
println(n)
end
end
println(3)
セルに記述された内容をレンダリングして出力
詳細はIPython.display
で解説
%load_ext sql
%%sql sqlite://
CREATE TABLE sample_table (name, age);
INSERT INTO sample_table VALUES ('Nagato', 16);
INSERT INTO sample_table VALUES ('Mikuru', 17);
%%sql
SELECT * from sample_table;
_.DataFrame()["age"].mean()
※ 以降はnbextensions
と表記
%matplotlib inline
import matplotlib.pyplot as plt
import numpy as np
def func(arg1, arg2):
"""Summary line.
Extended description of function.
Parameters
----------
arg1 : int
Description of arg1
arg2 : str
Description of arg2
Returns
-------
bool
Description of return value
"""
return
%load_ext pycodestyle_magic
%%pycodestyle
def f(x,y ):
return x**+y
print(3,2)
import pandas as pd
import numpy as np
from datetime import datetime
import ast
import ast
from datetime import datetime
import numpy as np
import pandas as pd
pd.DataFrame(data={"A":[1000,2000,3000,4000,5000,6000],"B":[.001,.002,.003,.004,.005,.006],},index=range(1,7),dtype=int,).reindex(range(1,10)).append(pd.DataFrame([[8000,.008]],columns=["A","B"])).interpolate(method="index",axis=0,limit=10000,inplace=False,limit_direction="forward",limit_area="inside",downcast="infer",)
ボタン1発で整形できる
pd.DataFrame(data={"A": [1000, 2000, 3000, 4000, 5000, 6000], "B": [.001, .002, .003, .004, .005, .006], }, index=range(1, 7), dtype=int,).reindex(range(1, 10)).append(
pd.DataFrame([[8000, .008]], columns=["A", "B"])).interpolate(method="index", axis=0, limit=10000, inplace=False, limit_direction="forward", limit_area="inside", downcast="infer",)
ボタン1発で整形できる
pd.DataFrame(
data={
"A": [1000, 2000, 3000, 4000, 5000, 6000],
"B": [.001, .002, .003, .004, .005, .006],
},
index=range(1, 7),
dtype=int,
).reindex(range(1, 10)).append(
pd.DataFrame([[8000, .008]], columns=["A", "B"])).interpolate(
method="index",
axis=0,
limit=10000,
inplace=False,
limit_direction="forward",
limit_area="inside",
downcast="infer",
)
セルマジックを使う
%load_ext blackcellmagic
%%black
pd.DataFrame(data={"A":[1000,2000,3000,4000,5000,6000],"B":[.001,.002,.003,.004,.005,.006],},index=range(1,7),dtype=int,).reindex(range(1,10)).append(pd.DataFrame([[8000,.008]],columns=["A","B"])).interpolate(method="index",axis=0,limit=10000,inplace=False,limit_direction="forward",limit_area="inside",downcast="infer",)
pd.DataFrame(
data={
"A": [1000, 2000, 3000, 4000, 5000, 6000],
"B": [.001, .002, .003, .004, .005, .006],
},
index=range(1, 7),
dtype=int,
).reindex(range(1, 10)).append(
pd.DataFrame([[8000, .008]], columns=["A", "B"])
).interpolate(
method="index",
axis=0,
limit=10000,
inplace=False,
limit_direction="forward",
limit_area="inside",
downcast="infer",
)
DisplayObject
を継承したクラスdisplay.HTML("<font color=red>Red</font>")
%%markdown
col1|col2
----|----
data|data
format
関数やf-stringと組み合わせられるhour = datetime.datetime.now().timetuple().tm_hour
oha = 4 <= hour < 11
kon = 11 <= hour < 18
ban = 18 <= hour or 0 <= hour < 4
greetings = np.array(["おはようございます", "こんにちは", "こんばんは"])
greeting = greetings[np.array([oha, kon, ban])][0]
display.Markdown(f"# みなさん{greeting}")
zen_op_python = "".join([this.d.get(c, c) for c in this.s]).split("\n")
tpl_text = """
#### {{ title }}
{% for item in item_list %}
* {{ item }}
{% endfor %}
"""
tpl = Template(tpl_text)
display.Markdown(
tpl.render({"title": zen_op_python[0], "item_list": zen_op_python[2:]})
)
zen_op_python = "".join([this.d.get(c, c) for c in this.s]).split("\n")
tpl_text = """
#### {{ title }}
{% for item in item_list %}
* {{ item }}
{% endfor %}
"""
tpl = Template(tpl_text)
display.Markdown(
tpl.render({"title": zen_op_python[0], "item_list": zen_op_python[2:]})
)
display.FileLinks("./sample/")
df1 = pd.DataFrame([[1, 2], [3, 4]])
df2 = pd.DataFrame([[10, 20], [30, 40]])
df1
df2
通常は最後のオブジェクトしか表示されない
display.display(df1)
display.display(df2)
class Json(object):
def __init__(self, json):
self.json = json
def _repr_pretty_(self, pp, cycle):
import json
pp.text(json.dumps(self.json, indent=2))
def __repr__(self):
return str(self.json)
display.display(Json({1: 2, 3: {4: 5}}))
for i in range(5):
print(i)
time.sleep(2)
display.clear_output(wait=True)
display
で一度表示した情報を更新display.display(pd.DataFrame(np.random.rand(4, 4)), display_id="df1")
for i in range(5):
display.update_display(pd.DataFrame(np.random.rand(4, 4)), display_id="df1")
time.sleep(1)
@interact(checked=True, selected=["A", "B", "C"])
def f(checked, selected):
return checked, selected
1.
の結果を確認def fund_returns(s0, mu, sigma, t, dt):
return s0 * np.exp(
np.cumsum(np.random.normal(mu * dt, sigma * np.sqrt(dt), round(t / dt)))
)
def get_return_and_risk(a, b):
weight = (a, b, 1 - sum((a, b)))
return_df = df * weight
return return_df.sum(axis=1).pct_change().var(), return_df.iloc[-1].sum() / 100
np.random.seed(9)
fund_a = fund_returns(100, 0.1, 0.15, 1, 0.01)
fund_b = fund_returns(100, 0.12, 0.4, 1, 0.01)
fund_c = fund_returns(100, 0.05, 0.1, 1, 0.01)
df = pd.DataFrame({"A": fund_a, "B": fund_b, "C": fund_c})
@interact(
a=FloatSlider(0.3, min=0.0, max=1.0, step=0.1, continuous_update=False),
b=FloatSlider(0.3, min=0.0, max=1.0, step=0.1, continuous_update=False),
)
def plot_return_and_risk(a, b):
c = 1 - sum((a, b))
fig = plt.figure(figsize=(14, 6))
ax1 = fig.add_subplot(1, 2, 1)
ax1.plot(fund_a, label="FundA")
ax1.plot(fund_b, label="FundB")
ax1.plot(fund_c, label="FundC")
ax2 = fig.add_subplot(1, 2, 2)
ax1.legend()
ax2.set_title(f"a:{a:.2}0%, b:{b:.2}0%, c:{c:.2}0%", fontsize=20)
ax2.set_xlim(0, 0.002)
ax2.set_xlabel("Risk", fontsize=20)
ax2.set_ylabel("Return", fontsize=20)
ax2.set_ylim(0.8, 1.5)
ax2.scatter(*get_return_and_risk(a, b), s=1000)
ax2.axvline(0.001, c="black")
ax2.axhline(1.0, c="black")
1.
を途中で変更するRISEを使うとインタラクティブなプレゼンが可能に
セルを読み取り専用にしたり、実行不可にできる
Rull All
を実行した際に、実行したくないセルをスキップできる%%tsumiki
:Markdown:
#### 段組みにしたい
:Markdown::
* よのなかのアスペクト比はどんどん横長に
* プレゼン資料で横長の文章は読みづらい
* 左右に分割して比較をしたい
:Markdown::
* ここには
* 有効なスペースが
* ありますよ
%%tsumiki
:Markdown:
#### Main Title
:Markdown::
##### Sub Title1
* col1
* Markdown
:HTML::
<h5>Sub Title2</h5>
<ul>
<li><font color="red">col2</font></li>
<li><font color="green">HTML</font></li>
</ul>
today = datetime.date.today()
tenki = [["23区", "晴れ"], ["練馬区", "ゲリラ豪雨"]]
%%tsumiki -r
:Markdown:
### {{ today }}日の天気は
{% for loc, weather in tenki %}
{{ loc }}は{{ weather }}
{% endfor %}
df1 = pd.DataFrame(np.random.rand(4, 4))
df2 = pd.DataFrame(np.random.rand(4, 4))
df1_html = df1.to_html()
df2_html = df2.to_html()
%%tsumiki -r
:HTML::
{{ df1_html }}
:HTML::
{{ df2_html }}
svg_data = StringIO()
fig, ax = plt.subplots()
ax.plot(df1)
fig.savefig(svg_data, format="SVG")
plt.close(fig)
svg_data.seek(0)
plot_data = svg_data.read()
%%tsumiki -r
:Markdown:
##### DataFrame and Plot
:HTML::
{{ df1_html }}
:HTML::
{{ plot_data }}
「Jupyterってdiffがなぁ・・・」
$ diff plot1.ipynb plot2.ipynb
22c22
< "[<matplotlib.lines.Line2D at 0x7f1ecc596710>]"
---
> "[<matplotlib.lines.Line2D at 0x7fb2184d9748>]"
31c31
< "image/png": "iVBORw0KGgoAAAANSUhEUgAAAXcAAAD8CAYAAACMwORRAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAALEgAACxIB0t1+/AAAADl0RVh0U29mdHdhcmUAbWF0cGxvdGxpYiB2ZXJzaW9uIDIuMi4yLCBodHRwOi8vbWF0cGxvdGxpYi5vcmcvhp/UCwAAIABJREFUeJzt3XlcVXX+x/HXVwUVRFzAFRE33EBLUbOasmxKzRazmWraraym2X+TmtZo2WI2M00zLY41LU5NzSS4pGWrZYtWWsmmKOKGGygKCLLe7+8P+P0eTqlc9cDhnvt+Ph48As6J8/564e3x3MPnGmstIiLiLU3cDiAiIs5TuYuIeJDKXUTEg1TuIiIepHIXEfEglbuIiAep3EVEPEjlLiLiQSp3EREPaubWgaOiomxcXJxbhxcRCUjr1q3bb6 ...
%%tsumiki
:Markdown:
#### nbdiff
:Markdown::
```bash
$ nbdiff plot1.ipynb plot2.ipynb
--- plot1.ipynb 2018-09-09 18:10:56.678277
+++ plot2.ipynb 2018-09-09 18:11:11.428336
## modified /cells/1/outputs/0/data/text/plain:
- [<matplotlib.lines.Line2D at 0x7f1ecc596710>]
+ [<matplotlib.lines.Line2D at 0x7fb2184d9748>]
## inserted before /cells/1/outputs/1:
+ output:
+ output_type: display_data
+ data:
+ image/png: iVBORw0K...<snip base64, md5=6d291fb88d778210...>
+ text/plain: <Figure size 432x288 with 1 Axes>
```
↗
:Markdown::
↘
```bash
## deleted /cells/1/outputs/1:
- output:
- output_type: display_data
- data:
- image/png: iVBORw0K...<snip base64, md5=f287ce2ad0448575...>
- text/plain: <Figure size 432x288 with 1 Axes>
## modified /cells/1/source:
@@ -1,2 +1,2 @@
fig, ax = plt.subplots()
-ax.plot([1, 2])
+ax.plot([1, 2], color="red")
```
ボタンでも表示できる
%%tsumiki
:Markdown:
#### GitHub vs nbviewer
:HTML::
<h5>GitHub</h5>
<img src="static/images/render_github.png">
:HTML::
<h5>nbviewer</h5>
<img src="static/images/render_nbviewer.png">
https://colab.research.google.com
GPU+CuPyでNumpyと同じ処理を実行
70倍の高速化
%%tsumiki
:Markdown:
#### 今回紹介したライブラリ
:Markdown::
* [Project Jupyter](http://jupyter.org)
* [Unofficial Jupyter Notebook Extensions](https://jupyter-contrib-nbextensions.readthedocs.io/en/latest/index.html)
* [pycodestyle](http://pycodestyle.pycqa.org/en/latest/)
* [pycodestyle_magic](https://github.com/mattijn/pycodestyle_magic)
* [isort](http://timothycrosley.github.io/isort/)
* [autopep8](https://github.com/hhatto/autopep8)
* [yapf](https://github.com/google/yapf)
* [Black](https://black.readthedocs.io/en/stable/index.html)
* [blackcellmagic](https://github.com/csurfer/blackcellmagic)
:Markdown::
* [ipython-sql](https://github.com/catherinedevlin/ipython-sql)
* [Hide_code](https://github.com/kirbs-/hide_code)
* [RISE](https://damianavila.github.io/RISE/)
* [nbdime](https://nbdime.readthedocs.io/en/stable/)
* [papermill](https://papermill.readthedocs.io/en/latest/)
* [CuPy](https://cupy.chainer.org)
ポスターセッションもよろしくネ