Skip to content

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)]

この現象が発生する主な原因は:

  1. NumPy 2.0で導入されたスカラー値の表示形式変更(公式リリースノート
  2. ローカル環境(NumPy 1.x)とCI環境(NumPy 2.x)のバージョン不一致
  3. テスト結果の比較で数値の等価性ではなく文字列表現をチェックしている

解決方法

方法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)

ベストプラクティス

  1. テストコードに対する推奨アプローチ

    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))
  2. システム全体のNumPy設定変更(推奨)

    python
    # プロジェクト初期化スクリプト(main.py等)で設定
    import numpy as np
    
    def configure_numpy():
        np.set_printoptions(legacy='1.25')
      
    if __name__ == '__main__':
        configure_numpy()
        # アプリケーション起動処理
  3. 環境ごとの挙動統一

    • 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環境での浮動小数点表示問題には:

  1. 短期対策 → np.set_printoptions(legacy='1.25')
  2. 中長期対策 → テスト比較方法の改善と環境統一
  3. 根本解決 → 数値比較はデータ型情報ではなく値で行う

プロジェクトの状況に合わせて段階的な対応を実施するのが推奨アプローチです。