складність 1/5 Безкоштовно
Jupyter Notebook
Документ, що чергує виконуваний код, текст і власні результати, виконуваний комірка за коміркою на живому ядрі, — стандартний інструмент розвідувального аналізу й відома загроза відтворюваності.
Інтуїція
Скрипт виконується згори вниз і видає результат десь в іншому місці. Блокнот тримає результат поруч із кодом, що його породив, і дозволяє перезапустити одну частину, не перезапускаючи решту. Для розвідки це саме те, що треба: більшість аналізу даних — це подивитися, підправити й подивитися знову, а робочий процес, який за кожної правки перезавантажує датафрейм на 2 ГБ, ви покинете.
Project Jupyter визначає артефакт широко: «блокнот — це документ, придатний для поширення, який поєднує комп’ютерний код, описи звичайною мовою, дані, насичені візуалізації на кшталт 3D-моделей, діаграм, графіків і рисунків, а також інтерактивні елементи керування» [1, What is a notebook?].
Ціна — зворотний бік тієї самої медалі. Свобода виконувати комірки в будь-якому порядку означає, що збережений документ не є записом того, що його породило. Блокноти «поєднують докладні робочі процеси з наративним текстом і візуалізацією результатів» [2, abstract] — і саме це поєднання робить їх водночас найкращим доступним інструментом розвідки й відомою проблемою відтворюваності.
Формальне визначення
Блокнот — це файл і протокол, і цей поділ важливий.
Файл. «Блокноти Jupyter є структурованими даними, що подають ваш код,
метадані, вміст і виводи. Збережений на диск, блокнот має розширення .ipynb і
використовує структуру JSON» [1, Architecture].
Кожна комірка несе свій код, свої виводи і свій лічильник виконання — тож виводи
зберігаються всередині документа, а не відтворюються з нього.
Ядро. Код виконується не в браузері. Ядро — це «окремий процес, відповідальний за виконання коду користувача й за такі речі, як обчислення можливих доповнень» [1, Architecture]. Воно тримає весь стан: ваші змінні живуть у тому процесі, а не у файлі.
З’єднання. «Фронтенди, як-от блокнот або консоль Qt, спілкуються з ядром IPython за допомогою JSON-повідомлень, надісланих через сокети ZeroMQ» [1, Architecture], і посередником є сервер: «браузер, файл блокнота на диску та ядро не можуть говорити одне з одним безпосередньо. Вони спілкуються через сервер Jupyter» [1, Architecture].
Отже, три окремі речі: документ, процес і канал між ними. Майже вся заплутана поведінка блокнотів походить із того, що забувають: перші дві — не одне й те саме.
Як це працює
Ви виконуєте комірку; фронтенд надсилає код ядру; ядро виконує його на стані, який уже тримає, і повертає виводи; фронтенд записує ці виводи назад у документ [1, Architecture].
Лічильник виконання у квадратних дужках зростає на одиницю за кожне виконання, глобально. Це число — єдиний слід, який файл зберігає про справжній порядок подій, і його легко змусити розійтися з порядком читання: видаліть комірку, чия змінна ще жива; відредагуйте й перезапустіть комірку 4 перед коміркою 3; перезапустіть ядро, поки старі виводи лишаються на екрані. У кожному з випадків збережений документ внутрішньо узгоджений і описує обчислення, якого більше не існує.
Масштаб наслідків виміряно. В автоматизованому дослідженні 27,271 блокнота з 2,660 репозиторіїв GitHub, пов’язаних із 3,467 біомедичними публікаціями, 15,817 блокнотів мали задекларовані залежності; з 10,388, чиї залежності вдалося встановити повністю і які потім перезапустили, 1,203 відпрацювали без жодних помилок, а 879 дали результати, тотожні наведеним в оригінальному блокноті [3, abstract].
Зіставте останній крок із першим: менш ніж один із двадцяти зібраних блокнотів відтворив власні опубліковані результати — і це вже після виключення всіх блокнотів, які взагалі не вдалося встановити.
Де застосовується
- Розвідувальний аналіз даних — випадок, у якому інструмент беззаперечно найкращий, і той, для якого його спроєктували.
- Навчання, де проза, код і результат на одній сторінці і є всім сенсом.
- Відтворювані публікації, коли це роблять свідомо: блокноти в поєднанні з репозиторіями коду й відкритими ліцензіями описано як потужні інструменти для «прозорого, спільного, відтворюваного й повторно використовуваного аналізу даних» [2, abstract].
- Прототипування моделей — ліва половина робочого процесу ML, до будь-якого пакування.
- Звіти й дашборди, через експорт до HTML або слайдів.
- Не лише Python. Ядро є окремим процесом, що говорить задокументованим протоколом [1, Architecture], тож R, Julia та інші під’єднуються до того самого фронтенду.
Чому і коли
Користуйтеся блокнотом, поки питання ще змінюється. Дешева ітерація на дорогому стані — це те, чого не робить більше ніщо.
Переходьте до модулів, коли відповідь перестала змінюватися. Усе, що
імпортують, тестують, ставлять на розклад чи рецензують, належить у файл .py.
Блокнот — погана одиниця програмного забезпечення: його версії погано
порівнюються, він незручно імпортується й геть не тестується.
Вважайте «Restart and run all» визначенням того, що воно працює. Блокнот, який працює лише в тому порядку, у якому ви випадково клікали, не є результатом — і наведені вище виміряні частки відтворення показують, як ця звичка виглядає в масштабі [3, abstract].
Декларуйте залежності. У тому самому дослідженні з 22,578 блокнотів на Python лише 15,817 мали залежності, задекларовані у стандартних файлах вимог, і лише 10,388 з них удалося справді встановити [3, abstract]. Відсутні або невстановні залежності зупинили 12,190 із них ще до запуску — більше, ніж 9,185, що потім завершилися винятком. Блокнот, який ніхто не може встановити, зазнав невдачі ще до того, як хтось узявся розглядати його логіку.
Практичний приклад
Аудит, який варто прогнати на будь-якому блокноті, якому ви збираєтесь довіряти, — зокрема на власному. Блокнот є JSON, тож жодних бібліотек не потрібно.
Python 27 рядків Показати код Сховати код
import json
# Блокнот — це JSON. Ось як насправді виглядає файл.
notebook = json.loads("""
{"nbformat": 4, "nbformat_minor": 5, "cells": [
{"cell_type": "code", "execution_count": 1,
"source": ["df = load('sales.csv')"], "outputs": []},
{"cell_type": "code", "execution_count": 3,
"source": ["df = df.dropna()"], "outputs": []},
{"cell_type": "code", "execution_count": 2,
"source": ["df['total'].mean()"],
"outputs": [{"output_type": "execute_result", "data": {"text/plain": "84.7"}}]},
{"cell_type": "code", "execution_count": null,
"source": ["plot(df['total'])"], "outputs": []}
]}
""")
code = [c for c in notebook["cells"] if c["cell_type"] == "code"]
counts = [c["execution_count"] for c in code]
print("execution counts, in document order:", counts)
ran = [n for n in counts if n is not None]
print("never executed :", counts.count(None))
print("executed out of order :", ran != sorted(ran))
print("has output but stale :",
any(c["outputs"] and c["execution_count"] != i + 1
for i, c in enumerate(code)))Вивід
execution counts, in document order: [1, 3, 2, None]
never executed : 1
executed out of order : True
has output but stale : TrueКожен із цих прапорців видно у файлі — і жодного не видно на відрендереній
сторінці, яку бачить читач. Середнє 84.7 обчислили на виконанні 2, до dropna
на виконанні 3, — отже, це середнє по рядках, яких очищений датафрейм більше не
містить. Блокнот упевнено показує його просто під кроком очищення, у розкладці,
що натякає на протилежний порядок.
Ніщо тут не є вадою Jupyter. Лічильники виконання записано сумлінно; просто читають не їх.
Типові помилки
Прихований стан. Змінні живуть у ядрі, а не в документі [1, Architecture]. Комірка, яку ви видалили, може й досі тримати блокнот на плаву, і ви дізнаєтесь про це лише тоді, коли його запустить хтось інший.
Виконання поза порядком. Випадок вище. Свідченням є лічильники, а не розкладка.
Коміт виводів. Виводи зберігаються в JSON [1, Architecture], через що версії блокнотів погано порівнюються, репозиторії роздуваються base64-зображеннями, а до коміту легко потрапляють дані, які ви мали намір лишити приватними.
Припущення, що воно запуститься деінде. У дослідженні відтворення незадекларовані або невстановні залежності зупинили більше блокнотів на Python (12,190), ніж усе, що пішло не так під час запуску (9,185) [3, abstract].
Дозволити блокнотові стати продуктом. Блокноти проєктувалися як документи для поширення [1, What is a notebook?], а не як програмне забезпечення для розгортання. Міграція до модулів — не формальність, яку хтось вам нав’язав; це момент, коли інструмент перестає відповідати задачі.
Ще не прочитаноДочитайте сторінку до кінця — і вона вважатиметься прочитаною.
Зберігайте свій прогресЗ доступом назавжди кожна дочитана сторінка позначається, і ви продовжуєте з того місця, де зупинилися, на всіх своїх пристроях.
Відкрити доступПеревірте себе
3 запитання
Кожну відповідь пояснено: який розділ вона перевіряє і з якого джерела.
Джерела
- Project Jupyter documentationdocs · звірено 2026-09-05https://docs.jupyter.org/en/latest/
- Ten Simple Rules for Reproducible Research in Jupyter Notebooks (2018)paperhttps://arxiv.org/abs/1810.08055
- Computational reproducibility of Jupyter notebooks from biomedical publications (2023)paperhttps://arxiv.org/abs/2308.07333