NumPy浮動小数点数のnp.float64
表示問題の解決策
問題概要
NumPy 2.0以降を使用するPython環境(Python 3.9+)で、テスト実行時に以下の表示問題が発生します:
Expected:
[13.0, 12.0, 7.0]
Got:
[np.float64(13.0), np.float64(12.0), np.float64(7.0)]
この現象が発生する主な原因は:
- NumPy 2.0で導入されたスカラー値の表示形式変更(公式リリースノート)
- ローカル環境(NumPy 1.x)とCI環境(NumPy 2.x)のバージョン不一致
- テスト結果の比較で数値の等価性ではなく文字列表現をチェックしている
解決方法
方法1: NumPyの表示オプションで旧形式を復元
python
import numpy as np
# 表示設定をNumPy 1.25以前の形式に変更
np.set_printoptions(legacy='1.25')
# これ以降の出力は [13.0, 12.0, ...] 形式になる
print(your_numpy_array)
特徴
- メリット: 既存コードの修正が最小限で済む
- デメリット: アプリケーション起動時にのみ有効で、モジュール間で状態を共有
- 適したケース: 大規模なコードベースを素早く修正したい場合
方法2: 依存バージョンを固定
requirements.txt
またはpyproject.toml
に以下を追加:
ini
# requirements.txtでの例
numpy ~> 1.26 # 1.26.x以上かつ2.0未満を意味する
toml
# pyproject.toml (Poetry利用時)
[tool.poetry.dependencies]
numpy = "~1.26"
注意点
- 長期的には非推奨のアプローチ(NumPy 2.xの機能改善が適用されない)
- 一時的対策として有効だが、将来の互換性問題が発生する可能性あり
方法3: データ型をPython標準に変換
python
import numpy as np
# NumPy配列 → Python標準floatリスト変換
python_list = list(map(float, your_numpy_array))
# 出力例: [13.0, 12.0, 7.0]
print(python_list)
応用パターン
数値精度を制御する場合:
python
formatted = [f"{x:.2f}" for x in your_numpy_array]
print(f"[{', '.join(formatted)}]")
# 出力: [13.00, 12.00, 7.00]
大規模配列の出力を最適化:
python
# sys.stdout経由で全要素出力(切り詰めなし)
import sys
np.savetxt(sys.stdout, your_numpy_array)
ベストプラクティス
テストコードに対する推奨アプローチ
python# Before (脆弱なテスト) # Expected: [13.0, 12.0, 7.0] # After (具体的な値で比較) expected = [13.0, 12.0, 7.0] result = calculate_something() assert all(a == b for a, b in zip(result, expected))
システム全体のNumPy設定変更(推奨)
python# プロジェクト初期化スクリプト(main.py等)で設定 import numpy as np def configure_numpy(): np.set_printoptions(legacy='1.25') if __name__ == '__main__': configure_numpy() # アプリケーション起動処理
環境ごとの挙動統一
- CI環境と開発環境で同一バージョンのNumPyを使用
- Dockerを使用した環境統一が理想
pip freeze > requirements.txt
でバージョン固定推奨
根本原因と技術的背景
NumPy 2.0でスカラー値のrepr()
実装が変更され:
python
# NumPy 1.x
repr(np.float64(13.0)) # → '13.0'
# NumPy 2.0
repr(np.float64(13.0)) # → 'np.float64(13.0)'
この変更は型情報を明示するための改善でしたが、文字列比較に依存した既存のテストに影響を与えました。
ケース別対応フローチャート
結論
NumPy 2.0環境での浮動小数点表示問題には:
- 短期対策 →
np.set_printoptions(legacy='1.25')
- 中長期対策 → テスト比較方法の改善と環境統一
- 根本解決 → 数値比較はデータ型情報ではなく値で行う
プロジェクトの状況に合わせて段階的な対応を実施するのが推奨アプローチです。