見出し画像

numpy 1.x系と2.x系の互換性由来の変なエラーについて

注意事項:
今回は問題の再現のためColab上のnumpyを一時的かつ無理やり2.x系に上げていますが、実際にColab上で無理やりnumpyを2.x系に上げて作業するのは他のパッケージにどう影響が出るか全くわからないため一切やるべきではありません。

Colabの環境

2024年11月現在、Google Colabのnumpyは未だ1.x系のままです。まず間違いなくColabの中核をなすパッケージとの互換性の問題ですが。

import numpy as np
import pandas as pd
print(f"numpy :{np.__version__}")
print(f"pandas:{pd.__version__}")
numpyは1.26.4、pandasは2.2.2

これは普通に使っているだけだとそんなに問題にならないんだけど、面倒なのは1.x系と2.x系環境間でのpandas.DataFrameの受け渡しの時です。そう、実はpandasの方で面倒が起きる。

再現(ファイル作成)

とりあえず現象を再現するためにファイルを作ってみる。これが一番起きるのはAnacondaとColab間のやり取りなんだけど、今回はColabで完結したいので逆になんとかする。嫌がるColabを尻目に2.x系numpyを仕込む。

インスタンスを再起動すれば一応2.x系が動く。

2.x系numpy環境で作ったpandas.DataFrame.to_pickle()の並列化ファイルを読み出す試行をしたいので適当にdfを作ってあげる。作業ディレクトリに置くとあとで1.x系に戻した時にファイルが消えるのでやむなくGoogle Driveに配置する。

d = pd.DataFrame({
    'obj_str':['a','b','c'],
    'obj_int': np.random.randint(3),
    'obj_float': np.random.randn(3),
})
d.to_pickle('/content/drive/MyDrive/2x.pkl')

再現(ファイル読み込み)

インスタンスを削除して起動してあげることで1.26.4に戻した上で、今作ったファイルを読み出してみると、

d = pd.read_pickle('/content/drive/MyDrive/2x.pkl')

ModuleNotFoundError: No module named 'numpy._core.numeric'

原因

pandasはDataFrameを作るにあたりnumpyの各種モジュールを使って各カラムのデータ型(dtype)を定義しているんだと思うんだけど、numpyは1.x系と2.x系で構造が全く異なるので、1.x系ではnumpy._core.numericなんてないんですよね。

そんなもんはない。

同じエラーに遭遇する人はちょくちょくいるみたいなんだけど、ModuleNotFoundError: No module named 'numpy._core.numeric'っていうエラーだけでは1.x系と2.x系の違いに由来するエラーだってことにはなかなか気づけないのでここに書き残しておきます。

あーあ、ColabもDockerみたいにPython環境とコンテナイメージ選んで立ち上げる感じになんないかなー。ちなみにColabで無理やりDockerコンテナを立ち上げて異なるnumpy環境を作って今回の問題を打破する方法: 『Colab上のDockerコンテナでAnacondaを動かす (docker-in-colab)』も過去に書いてますが、まあColabの上でさらにDocker走らせるとどうしても使いづらくなるのは事実。

いいなと思ったら応援しよう!