Короткий ответ
Расхождение чаще всего вызвано разными версиями библиотек (например, pandas 1.x vs 2.x меняет поведение некоторых операций), незафиксированным random seed при сэмплировании/разбиении данных, или использованием другой версии самого файла; для воспроизводимости нужно фиксировать версии окружения, seed и источник данных.
Как это работает подробнее
- Как это работает: разные версии pandas могут по-разному обрабатывать типы данных (например, nullable integer vs float при наличии пропусков), сортировку при группировке или поведение
groupbyс NaN в ключах; если в коде естьdf.sample(),train_test_splitили любая случайность без фиксированногоrandom_state/seed, результат будет меняться от запуска к запуску даже на одном компьютере.
Пример кода
reproducibility.sh
sha256sum orders.csv
pip freeze | grep -E "pandas|numpy" > requirements_check.txt
import numpy as np
np.random.seed(42)
sample = df.sample(frac=0.1, random_state=42)Что использовать на практике
- На практике: воспроизводимость обеспечивается связкой: файл с зафиксированными версиями пакетов (
requirements.txtс точными версиями илиenvironment.yml), явныйrandom_state=42везде, где есть случайность, и неизменность входных данных — лучше хранить хэш файла данных (например, черезsha256sum) или версионировать сами данные, а не полагаться на то, что файл с тем же именем не менялся. - Пример и проверка. Проверка: если хэши orders.csv у обоих аналитиков совпадают, а версии pandas/numpy и seed одинаковы, то результат sample.describe() должен быть идентичным; расхождение хотя бы в одном из этих трёх факторов — наиболее вероятная причина разных чисел.
Подводные камни
- Частые ошибки: указывать в
requirements.txtзависимости без версий (pandas,numpy) вместо точных версий (pandas==2.1.4); забывать зафиксировать seed в операциях типаdf.sample(frac=0.1)илиnp.random.choice; не проверять, что оба аналитика действительно используют один и тот же файл, а не два похожих экспорта с разных дат.