Особливості Jupyter Notebook, про яких ви (може бути) не чули

Jupyter Notebook – це вкрай зручний інструмент для створення красивих аналітичних звітів, так як він дозволяє зберігати разом код, зображення, коментарі, формули і графіки:



Нижче ми розповімо про деякі фішки, які роблять Jupyter дуже крутим. Про них можна прочитати і в інших місцях, але якщо спеціально не задаватися цим питанням, то ніколи і не прочитаєш.

Jupyter підтримує безліч мов програмування і може бути легко запускається на будь-якому сервері, необхідний лише доступ по ssh або http. До того ж це вільне.

Основи
Список хоткея ви знайдете в Help > Keyboard Shortcuts (список періодично доповнюється, так що не соромтеся заглядати туди знову).

Звідси можна отримати уявлення про взаємодію з блокнотом (notebook). Якщо ви будете постійно працювати c Jupyter, більшість комбінацій ви швидко вивчите.

Наприклад,

  • Esc + F
    дозволить знайти і замінити тільки в коді, не враховуючи висновок;
  • Esc + O
    перейти на висновок осередку;
  • Можна вибрати декілька комірок і видалити/копіювати/вирізати/вставити. Це корисно при необхідності переміщати частини блокнота.


Експорт блокнота
Найпростіший спосіб — зберегти блокнот у форматі IPython Notebook (.ipynb), але так як їх використовують не всі, є й інші варіанти:

  • Перетворити блокнот в html-файл;
  • Опублікувати gists, який вміє обробляти файли цього формату (приклад;
  • Зберегти ваш блокнот, наприклад, dropbox, а потім відкрити посилання в nbviewer;
  • Блокноти вміє відкривати github (є деякі обмеження, але в більшості випадків працює), що дуже корисно, так як дозволяє зберігати історію дослідження (якщо дослідження доступне широкій публіці).
Побудова графіків
Є кілька варіантів побудови графіків:

  • matplotlib (фактично, стардарт), включається командою
    %matplotlib inline
    ;
  • %matplotlib notebook
    — інтерактивний режим, але працює дуже повільно, так як обробка графіка відбувається на стороні сервера;
  • mpld3 — альтернативна бібліотека візуалізації (використовує D3) для matplotlib. Вона досить гарна, хоча і неповною.
  • bokeh краще підходить для побудови інтерактивних графіків;
  • plot.ly будує красиві графіки, але це буде коштувати грошей.


Magic-команди
Магічні команди (magics) перетворюють звичайний python магічний python. Magic-команди — це ключ до могутності IPython'а.

# list available python magics
%lsmagic

Available line magics:
%alias %alias_magic %autocall %automagic %autosave %bookmark %cat %cd %clear %colors %config %connect_info %cp %debug %dhist %dirs %doctest_mode %ed %edit %env %gui %hist %history %killbgscripts %ldir %less %lf %lk %ll %load %load_ext %loadpy %logoff %logon %logstart %logstate %logstop %ls %lsmagic %lx %macro %magic %man %matplotlib %mkdir %more %mv %notebook %page %pastebin %pdb %pdef %pdoc %pfile %pinfo %pinfo2 %popd %pprint %precision %profile %prun %psearch %psource %pushd %pwd %pycat %pylab %qtconsole %quickref %recall %rehashx %reload_ext %rep %rerun %reset %reset_selective %rm %rmdir %run %save %sc %set_env %store %sx %system %tb %time %timeit %unalias %unload_ext %who %who_ls %whos %xdel %xmode

Available cell magics:
%%! %%HTML %%SVG %%bash %%capture %%debug %%file %%html %%javascript %%js %%latex %%perl %%prun %%pypy %%python %%python2 %%python3 %%ruby %%script %%sh %%svg %%sx %%system %%time %%timeit %%writefile

Automagic is ON, % prefix IS NOT needed for line magics.

%env
Можна керувати змінними середовища для вашого блокнота без перезапуску Jupyter-сервера. Деякі бібліотеки (такі, як theano) використовують змінні середовища, щоб контролювати поведінку, і %env — найзручніший спосіб.

#%env - without arguments lists environmental variables
%env OMP_NUM_THREADS=4

env: OMP_NUM_THREADS=4

Виконання shell-команд
У Notebook можна викликати будь-яку shell-команду. Це особливо зручно для управління віртуальним середовищем.

!pip install numpy
!pip list | grep Theano

Requirement already satisfied (use --upgrade to upgrade): numpy in /Users/axelr/.venvs/rep/lib/python2.7/site-packages
Theano (0.8.2)

Придушення виведення останнього рядка
Іноді висновок не потрібен, і в цьому випадку можна або використовувати команду pass з нового рядка, або поставити крапку з комою в кінці рядка:

%matplotlib inline
from matplotlib import pyplot as plt
import numpy

# if you don't put semicolon at the end, you'll have output of function printed
plt.hist(numpy.linspace(0, 1, 1000)**1.5);



Перегляд вихідних функцій/класів/чого завгодно з допомогою знаку питання (?, ??)
from sklearn.cross_validation import train_test_split
# show the sources of train_test_split function in the pop-up window
train_test_split??

# you can use ? to get details about magics, for instance:
%pycat?

викличе таке спливаюче вікно:

Show a syntax-highlighted file through a pager.

This magic is similar to the cat utility, but it will assume the file
to be Python source and will show it with syntax highlighting.

This magic command can either take a local filename, an url,
an history range (see %history) or as a macro argument ::

%pycat myscript.py
%pycat 7-27
%pycat myMacro
%pycat http://www.example.com/myscript.py

Використовуйте %run для виконання коду на Python
%run може виконати код на мові Python з файлів з розширенням .py — це поведінка добре задокументовано.

Але ця команда може виконувати й інші блокноти з Jupyter! Іноді це дуже корисно.

Зверніть увагу, що %run — це не те ж, що імпорт python-модуля.

# execute this will all the code cells from different notebooks
%run ./2015-09-29-NumpyTipsAndTricks1.ipynb

[49 34 49 41 59 45 30 33 34 57]
[172 177 209 197 171 176 209 208 166 151]
[30 33 34 34 41 45 49 49 57 59]
[209 208 177 166 197 176 172 209 151 171]
[1 0 4 8 6 5 2 9 7 3]
['a' 'b' 'c', 'd' 'e' 'f' 'g' 'h' 'i' 'j']
['b' 'a' 'e' 'i' 'g' 'f' 'c', 'j' 'h' 'd']
['a' 'b' 'c', 'd' 'e' 'f' 'g' 'h' 'i' 'j']
[1 0 6 9 2 5 4 8 3 7]
[1 0 6 9 2 5 4 8 3 7]
[ 0.93551212 0.75079687 0.87495146 0.3344709 0.99628591 0.34355057
0.90019059 0.88272132 0.67272068 0.24679158]
[8 4 5 1 9 2 7 6 3 0]





[-5 -4 -3 -2 -1 0 1 2 3 4]
[0 0 0 0 0 0 1 2 3 4]
['eh' 'cl' 'ah' ..., 'ab' 'bm' 'ab']
['ab' 'ac' 'ad' 'ae' 'af' 'ag' 'ah' 'ai' 'aj' 'ak' 'al' 'am' 'an' 'bc' 'bd'
'be' 'bf' 'bg' 'bh' 'bi' 'bj' 'bk' 'bl' 'bm' 'bn' 'cd' 'ce' 'cf' 'cg' 'ch'
'ci' 'cj' 'ck' 'cl' 'cm' 'cn' 'de' 'df' 'dg' 'dh' 'di' 'dj' 'dk' 'dl' 'dm'
'dn' 'ef' 'eg' 'eh' 'ei' 'ej' 'ek' 'el' 'em' 'en' 'fg' 'fh' 'fi' 'fj' 'fk'
'fl' 'fm' 'fn' 'gh' 'gi' 'gj' 'g' 'gl' 'gm' 'gn' 'hi' 'hj' 'hk' 'hl' 'hm'
'n' 'ij' 'ik' 'il' 'im' 'in' 'jk' 'jl' 'jm' 'jn' 'kl' 'km' 'kn' 'lm' 'ln'
'mn']
[48 33 6 ..., 0 23 0]
['eh' 'cl' 'ah' ..., 'ab' 'bm' 'ab']
['eh' 'cl' 'ah' ..., 'ab' 'bm' 'ab']
['bf' 'cl' 'dn' ..., 'dm' 'cn' 'dj']
['bf' 'cl' 'dn' ..., 'dm' 'cn' 'dj']



[ 2.29711325 1.82679746 2.65173344 ..., 2.15286813 2.308737 2.15286813]
1000 loops, best of 3: 1.09 ms per loop
The slowest run took 8.44 times longer than the fastest. This could mean that an intermediate result is being cached.
10000 loops, best of 3: 21.5 μs per loop


0.416
0.416

%load
Завантажить код безпосередньо в комірку. Можна вибрати файл локально або в мережі.

Якщо розкоментувати і виконати код нижче, вміст комірки заміниться на вміст файлу.

# %load http://matplotlib.org/mpl_examples/pylab_examples/contour_demo.py

%store — лінива передача даних між блокнотами
data = 'this is the string I want to pass to different notebook'
%data store
del data # deleted variable

Stored 'data' (str)

# in second notebook I will use:
%store -r data
print data

this is the string I want to pass to different notebook

%who для аналізу змінних глобального простору імен
# pring names of string variables
%who str

data 

Таймінг
Якщо ви хочете заміряти час виконання програми або знайти вузьке місце в коді, на допомогу прийде IPython.

%%time
import time
time.sleep(2) # sleep for two seconds

CPU times: user 1.23 ms, sys: 4.82 ms, total: 6.05 ms
Wall time: 2 s

# measure small code snippets with timeit !
import numpy
%timeit numpy.random.normal size=100)

The slowest run took 13.85 times longer than the fastest. This could mean that an intermediate result is being cached.
100000 loops, best of 3: 6.35 μs per loop

%%writefile pythoncode.py

import numpy
def append_if_not_exists(arr, x):
if x not in arr:
arr.append(x)

def some_useless_slow_function():
arr = list()
for i in range(10000):
x = numpy.random.randint(0, 10000)
append_if_not_exists(arr, x)

Overwriting pythoncode.py

# shows highlighted source of the newly-file created
%pycat pythoncode.py

from pythoncode import some_useless_slow_function, append_if_not_exists

Профілювання: %prun, %lprun, %mprun
# shows how much time program spent in each function
%prun some_useless_slow_function()

Приклад виводу:

26338 function calls in seconds 0.713

Ordered by: internal time

ncalls tottime percall cumtime percall filename:lineno(function)
10000 0.684 0.000 0.685 0.000 pythoncode.py:3(append_if_not_exists)
10000 0.014 0.000 0.014 0.000 {method 'randint' of 'mtrand.RandomState' objects}
1 0.011 0.011 0.713 0.713 pythoncode.py:7(some_useless_slow_function)
1 0.003 0.003 0.003 0.003 {range}
6334 0.001 0.001 0.000 0.000 {method 'append' of 'list' objects}
1 0.000 0.000 0.713 0.713 <string>:1(<module>)
1 0.000 0.000 0.000 0.000 {method 'disable' of '_lsprof.Profiler' objects}

%load_ext memory_profiler

# tracking memory consumption (show in the pop-up)
%mprun -f append_if_not_exists some_useless_slow_function()

(",)

Приклад виводу:

Line # Mem usage Increment Line Contents
================================================
3 20.6 MiB 0.0 MiB def append_if_not_exists(arr, x):
4 20.6 MiB 0.0 MiB if x not in arr:
5 20.6 MiB 0.0 MiB arr.append(x)

%lprun дозволяє профілювати з точністю до рядків коду, але, здається, в останньому релізі Python він не працює, так що цього разу обійдемося без магії:

import line_profiler
lp = line_profiler.LineProfiler()
lp.add_function(some_useless_slow_function)
lp.runctx('some_useless_slow_function()', locals=locals(), globals=globals())
lp.print_stats()

Timer unit: 1e-06 s

Total time: 1.27826 s
File: pythoncode.py
Function: some_useless_slow_function at line 7

Line # Hits Time Per Hit % Time Line Contents
==============================================================
7 def some_useless_slow_function():
8 1 5 5.0 0.0 arr = list()
9 10001 17838 1.8 1.4 for i in range(10000):
10 10000 38254 3.8 3.0 x = numpy.random.randint(0, 10000)
11 10000 1222162 122.2 95.6 append_if_not_exists(arr, x)

Дебаг з допомогою %debug
У Jupyter є власний інтерфейс для ipdb, що дозволяє зайти всередину функції і подивитися, що в ній відбувається.

Це не PyCharm — потрібен час, щоб освоїти, але при необхідності дебага на сервері це може бути єдиним варіантом (крім pdb через термінал).

#%%debug filename:line_number_for_breakpoint
# Here some code that fails. This will activate interactive context for debugging

Трохи більш простий спосіб — команда %pdb, яка активує дебагер, коли викидається виняток:

# %pdb

# def pick_and_take():
# picked = numpy.random.randint(0, 1000)
# raise NotImplementedError()

# pick_and_take()

Запис формул LateX
Маркдаун осередки можуть відтворення формул LateX з допомогою MathJax.

P(A|B) = {P(B|A)P(A) \over P(B)}
Маркдаун — важлива частина блокнотів, так що не забувайте використовувати його виражальні можливості!

Використання різних мов всередині одного блокнота
Якщо ви скучили по іншим мовам програмування, можете використовувати їх в Jupyter Notebook:

  • %%python2
  • %%python3
  • %%ruby
  • %%perl
  • %%bash
  • %%R,
але, зрозуміло, середа повинна бути налаштована відповідним чином.

%%ruby
puts 'Hi, this is ruby.'

Hi, this is ruby.

%%bash
echo 'Hi, this is bash.'

Hi, this is bash.


Аналіз Big Data
Існує кілька рішень, щоб запитувати/обробляти великі обсяги даних:

  • ipyparallel (колишній ipython cluster) — хороший інструмент для простих операцій map-reduce на Python. Ми використовуємо його в rep для навчання великої кількості моделей машинного навчання паралельно.
  • pyspark
  • spark-sql magic %%sql
Ваші колеги можуть експериментувати з вашим кодом, нічого не встановлюючи
Такі сервіси, як mybinder, надають доступ до Jupiter Notebook з усіма встановленими бібліотеками, так що користувач може з півгодини погратися з вашим кодом, маючи під рукою тільки браузер.

Ви також можете встановити вашу власну системи за допомогою jupyterhub, що дуже зручно, якщо ви проводите міні-курс або майстер-клас і вам колись думати про машини для студентів.

Написання функцій на інших мовах
Іноді швидкості NumPy буває недостатньо, і мені необхідно написати трохи швидкого коду. В принципі, можна зібрати потрібні функції в динамічні бібліотеки, а потім написати обгортку на Python…

Але набагато краще, коли нудна частина роботи зроблена за нас, правда?

Адже можна написати потрібні функції на Cython або Fortran і використовувати їх безпосередньо з коду на Python.

Для початку потрібно встановити модулі

!pip install cython fortran-magic

%load_ext Cython

%%cython
def myltiply_by_2(float x):
return 2.0 * x

myltiply_by_2(23.)

46.0 

Особисто я віддаю перевагу Fortran, на якому, я вважаю, що зручно писати функції для обробки великого обсягу чисельних даних. Детальніше про його використанні можна почитати тут.

%load_ext fortranmagic

/Users/axelr/.venvs/rep/lib/python2.7/site-packages/IPython/utils/path.py:265: UserWarning: get_ipython_cache_dir has moved to the IPython.paths module
warn("get_ipython_cache_dir has moved to the IPython.paths module")

%%fortran
subroutine compute_fortran(x, y, z)
real, intent(in) : x(:), y(:)
real, intent(out) : z(size(x, 1))

z = sin(x + y)

end subroutine compute_fortran

compute_fortran([1, 2, 3], [4, 5, 6])

array([-0.95892429, 0.65698659, 0.41211849], dtype=float32)

Повинен зауважити, що є й інші способи прискорити ваш код на Python. Приклади можна знайти в моєму блокноті.

Множинний курсор
З недавнього часу Jupyter підтримує множинний курсор, такий, як у Sublime або IntelliJ!


Джерело: swanintelligence.com/multi-cursor-in-jupyter.html

Розширення Jupyter-contrib
встановлюються за допомогою

!pip install https://github.com/ipython-contrib/jupyter_contrib_nbextensions/tarball/master
!pip install jupyter_nbextensions_configurator
!jupyter contrib nbextension install --user
!jupyter nbextensions_configurator enable --user



Це ціле сімейство різних розширень, включаючи, наприклад, jupyter spell-checker і code-formatter, яких за замовчуванням в Jupyter немає.

RISE: презентації в Notebook
Розширення, написане Damian Avila, дозволяє демонструвати блокноти як презентації. Приклад такої презентації: bollwyvl.github.io/live_reveal/#/7

Це може стати в нагоді, якщо ви навчаєте використання якої-небудь бібліотеки.

Система виведення Jupyter
Блокноти відображаються в HTML, і висновок осередку теж може бути в форматі HTML, так що ви можете виводити все, що душі завгодно: відео, аудіо, зображення.

У цьому прикладі я переглядаю вміст директорії з картинками в моєму репозиторії і отображаю перші п'ять з них.

import os
from IPython.display import display, Image
names = [f for in f os.listdir('../images/ml_demonstrations/') if f.endswith('.png')]







Я міг би отримати той же список bash-командою,
тому що magic-команди і bash-виклики повертають Python змінні:

names = !ls ../images/ml_demonstrations/*.png
names[:5]

['../images/ml_demonstrations/colah_embeddings.png',
'../images/ml_demonstrations/convnetjs.png',
'../images/ml_demonstrations/decision_tree.png',
'../images/ml_demonstrations/decision_tree_in_course.png',
'../images/ml_demonstrations/dream_mnist.png']


Повторне підключення до ядра
Давним давно, якщо ви запускали який-небудь довгий процес і в якийсь момент підключення до сервера IPython переривалося, ви повністю втрачали можливість відстежувати процес обчислень (якщо тільки ви не записували ці дані в файл). Доводилося або переривати роботу ядра з ризиком втратити деякі результати, або чекати закінчення процесу, не маючи уявлення про те, що в даний момент відбувається.

Тепер опція
Reconnect to kernel
дозволяє заново підключитися до працюючого ядру, не перериваючи обчислень, і побачити останній висновок (хоча якась частина виведення все ж буде втрачена).

Пишіть ваші пости в Notebook
такі, як . Використовуйте nbconvert, щоб експортувати в HTML.

Корисні посилання
Notebook з оригіналом цього поста можна завантажити з репозитория.
Джерело: Хабрахабр

0 коментарів

Тільки зареєстровані та авторизовані користувачі можуть залишати коментарі.