2025, Dec 18 06:02
Как избежать ModuleNotFoundError: numpy._core.numeric при сериализации pandas DataFrame через pickle
Разбираем ModuleNotFoundError: numpy._core.numeric при загрузке pandas DataFrame из pickle и даем решение: используйте pickle.dump с протоколом по умолчанию.
Обмениваться объектом pandas DataFrame между машинами через pickle кажется простой задачей, пока неожиданная ошибка импорта не прервёт работу. DataFrame, сохранённый в pickle на одной системе, локально читается без проблем, но на другой машине загрузка может упасть с ModuleNotFoundError, указывающей на numpy._core.numeric, даже если версии pandas и numpy совпадают. Причина кроется не в способе загрузки, а в том, как объект изначально сериализовали.
Воспроизведение сбоя
DataFrame сериализовали на машине A с помощью встроенного метода, а на машине B пытались десериализовать как обычным загрузчиком pickle, так и обёрткой pandas. В обоих случаях ошибка стабильно повторялась.
frame.to_pickle('bundle.pkl')
with open('path/to/bundle.pkl','rb') as fh:
restored_obj = pickle.load(fh)
restored_obj = pd.read_pickle('path/to/bundle.pkl')
ModuleNotFoundError: No module named 'numpy._core.numeric'
В обоих окружениях использовались pandas 2.2.2 и numpy 1.26.4. Синхронизация версий помогала некоторым пользователям, но в этом случае — нет.
Что на самом деле происходит
Поведение зависит от способа сериализации и выбранного протокола pickle. Объекты, сохранённые встроенным путём сериализации pandas или выгруженные с использованием максимально доступного протокола pickle, при чтении обратно давали ту же ошибку импорта — независимо от того, загружались ли они через pickle.load или pd.read_pickle. Напротив, простой pickle.dump с протоколом по умолчанию проблему обходил.
Рабочий подход
Сериализация DataFrame через pickle.dump с протоколом по умолчанию делает артефакт переносимым между машинами. Затем его можно успешно загрузить как стандартным загрузчиком pickle, так и через pandas.read_pickle.
with open('safe_dump.pkl','wb') as fh:
pickle.dump(frame, fh)
with open('path/to/safe_dump.pkl','rb') as fh:
revived = pickle.load(fh)
revived = pd.read_pickle('path/to/safe_dump.pkl')
Однако, если принудительно указать максимальный протокол при сохранении, при загрузке сбой повторяется — ровно как и раньше.
with open('safe_dump.pkl','wb') as fh:
pickle.dump(frame, fh, protocol=pickle.HIGHEST_PROTOCOL)
Почему этот нюанс важен
Данные-артефакты часто кочуют между ноутбуками, задачами CI и разными машинами. Когда простой шаг сохранения становится зависимым от окружения, в конвейеры закрадывается скрытая хрупкость. В этой истории дело было не в способе загрузки, а в пути сериализации и выбранном протоколе. Помня об этом, можно избежать трудно диагностируемых падений во вложенных задачах, где ожидается полная совместимость.
Практические выводы
Если при распаковке pandas DataFrame на другой машине вы видите ModuleNotFoundError: No module named 'numpy._core.numeric', создавайте артефакт через pickle.dump с протоколом по умолчанию. Для этого сценария не следует принудительно использовать pickle.HIGHEST_PROTOCOL. Если объект ранее сериализовали методом DataFrame.to_pickle и возникает сбой, пересохраните его через pickle.dump и проверьте снова. Одного совпадения версий может быть недостаточно — здесь важен именно путь сериализации. Быстрый тест сериализации и обратной загрузки на второй машине перед включением артефакта в рабочий процесс сэкономит время и убережёт от путаницы.