Python

SciPyとは?読み方・インストール・使い方をコード例で解説【SciPy 1.18】

SciPyとは?読み方・インストール・使い方をコード例で解説【SciPy 1.18】

SciPy(サイパイ)は、NumPyの配列を使って最適化・数値積分・統計・信号処理・補間などを行うPythonの科学技術計算ライブラリです。この記事では、公式の読み方、NumPyとの役割の違い、pip install scipy の手順と失敗したときの対処、目的別のコード例を、2026年10月時点の最新版SciPy 1.18.1で実行した結果とあわせて説明します。

まとめ:SciPyの要点

  • 読み方は「サイパイ」。SciPy公式のREADMEにpronounced "Sigh Pie"と書かれています。
  • NumPyは配列そのものと基本演算、SciPyはその配列に対する数値計算の手法(最小化・積分・検定・フィルタ・補間)を受け持ちます。SciPyを入れるとNumPyも依存として入ります。
  • 最新版はSciPy 1.18.1(2026年8月21日)で、Python 3.12以上が必要です。Python 3.11で pip install scipy を実行すると、エラーにならずに1.17.1が入ります。
  • インストールで「Unknown compiler(s)」が出たら、wheel(ビルド済みの配布物)が無い環境でソースビルドに落ちています。コンパイラを入れる前に、Pythonの版と64ビット版かどうかを確かめます。
  • バージョンは scipy.__version__ で確認します。scipy.odrは1.17.0で非推奨になり、1.19.0で削除される予定です。

SciPyの読み方は「サイパイ」

SciPyの読み方は「サイパイ」です。根拠は開発元の表記で、SciPyのGitHubリポジトリのREADMEの冒頭にSciPy (pronounced "Sigh Pie")とあります。カタカナで書くなら「サイパイ」です。

近いライブラリでは、scikit-learnは公式FAQに「sy-kit learn」(サイキット・ラーン)と書かれています。NumPyは公式サイトとリポジトリに読み方の記述がなく、「ナムパイ」「ナンパイ」の両方が使われています。NumPyの読み方の根拠はNumPyとは?読み方・インストール・基本的な使い方で詳しく扱っています。

SciPyでできること:サブパッケージ一覧

SciPyの機能は分野ごとのサブパッケージに分かれています。SciPy 1.18の公式APIリファレンスに載っているのは次の18個です。最適化・統計・積分など、本記事で扱う用途を中心に並べました。

サブパッケージ 用途 代表的な関数・クラス
scipy.optimize 最小化・曲線あてはめ・線形計画・求根 minimize, curve_fit, linprog, root_scalar
scipy.stats 確率分布・統計検定・相関 norm, ttest_ind, pearsonr
scipy.integrate 数値積分・常微分方程式 quad, solve_ivp
scipy.interpolate 補間・スプライン CubicSpline, make_interp_spline
scipy.linalg 線形代数(NumPyより多い分解・行列関数) solve, lu, expm, eigh
scipy.signal フィルタ設計・スペクトル解析 butter, sosfiltfilt, welch
scipy.fft 高速フーリエ変換 fft, rfft, rfftfreq
scipy.sparse 疎行列 csr_array, linalg.spsolve
scipy.spatial 近傍探索・距離・凸包 KDTree, distance.cdist
scipy.ndimage 多次元画像処理 gaussian_filter, label
scipy.cluster 階層的クラスタリング・k-means hierarchy.linkage, vq.kmeans2
scipy.special 特殊関数 gamma, erf, comb
scipy.io MATLAB・WAVなどの読み書き loadmat, wavfile.read
scipy.constants 物理定数・単位換算 c, h, physical_constants
scipy.differentiate 数値微分 derivative, jacobian
scipy.datasets サンプルデータの取得 face, ascent
scipy.fftpack 旧FFT(新規はscipy.fft) fft
scipy.odr 直交距離回帰(非推奨) ODR

このほかに、インストールしたSciPy 1.18.1には一覧に載っていない scipy.misc も残っています。importすると「scipy.misc is deprecated and will be removed in 2.0.0」という警告が出るので、新しいコードでは使いません。

SciPyとNumPyの違い:配列はNumPy、計算手法はSciPy

NumPyは多次元配列 ndarray と、その配列に対する四則演算・集計・基本的な線形代数を提供します。SciPyはNumPyの配列を入力に取り、その上で「最小値を探す」「積分する」「検定する」といった数値計算の手法を提供します。SciPyはNumPyに依存しますが、利用者のコードでNumPyを直接importする必要があるかは、処理によって異なります。SciPy 1.18.1はNumPy 2.0.0以上2.8未満を依存として要求するので(SciPy 1.18.1のpyproject.toml)、pip install scipy だけでNumPyも入ります。

違いが出るのは、NumPyに関数が無い処理です。SciPy 1.18.1とNumPy 2.5.4で確かめた結果を表にしました。

やりたいこと NumPy 2.5.4 SciPy 1.18.1
連立一次方程式 np.linalg.solve scipy.linalg.solve
LU分解 なし scipy.linalg.lu
行列指数関数 なし scipy.linalg.expm
関数の最小化 なし scipy.optimize.minimize
定積分 なし(台形則のnp.trapezoidのみ) scipy.integrate.quad
補間 np.interp(線形のみ) CubicSpline など
近傍点の探索 なし scipy.spatial.KDTree

補間の差は数値で見るとわかりやすいです。y=x²の点(x=0〜4)から x=2.5 の値を求めると、np.interp は線形補間なので6.5、CubicSpline は6.25(真の値と一致)を返しました。線形補間で十分ならNumPyで対応でき、補間曲線の滑らかさが必要ならSciPyのCubicSplineが候補になります。

import numpy as np
from scipy.interpolate import CubicSpline

xs = np.array([0, 1, 2, 3, 4])
ys = xs ** 2
print(np.interp(2.5, xs, ys))        # 6.5
print(float(CubicSpline(xs, ys)(2.5)))  # 6.25

データの読み込みや集計はpandas、学習モデルはscikit-learnと分担するのが一般的です。scikit-learnは内部でSciPyを使っており、Scikit-learnとは?読み方・できること・使い方で入れたときにもSciPyが一緒に入ります。

SciPyのインストール手順(pip・uv・conda)

pip install scipy の手順

pipで入れる場合は、仮想環境を作ってから入れます。SciPy公式のインストールガイドも、venvで環境を作って有効化したあとに python -m pip install scipy を実行する手順を示しています。pip を直接呼ぶより python -m pip の方が、どのPythonに入るかを取り違えません。

# macOS / Linux
python3 -m venv .venv
source .venv/bin/activate
python -m pip install --upgrade pip
python -m pip install scipy
python -c "import scipy; print(scipy.__version__)"

# Windows(PowerShell)
py -m venv .venv
.venv\Scripts\Activate.ps1
python -m pip install --upgrade pip
python -m pip install scipy

Python 3.12で実行すると、SciPy 1.18.1とNumPy 2.5.4が入りました。wheelの大きさは、macOS(Intel、macOS 14以降向け)で23.1MB、Linux x86_64で35.3MB、Windows x64で36.7MBです(PyPIの1.18.1の配布ファイル)。

uv・condaによるSciPyの導入

公式ガイドは、新しく始める人にはuvやpixiによるプロジェクト単位の管理を勧めています。uvなら uv init でプロジェクトを作り、uv add scipy で依存に加えます。

uv init myproject
cd myproject
uv add scipy
uv run python -c "import scipy; print(scipy.__version__)"

condaを使う場合、公式ガイドはMiniforgeを勧めており、環境を作ってから conda install scipy でconda-forgeから入れます。condaの環境にpipで同じパッケージを重ねると依存が壊れることがあるため、どちらか一方に寄せます。使い分けはpipとcondaの違いと使い分けにまとめています。

Pythonのバージョン別・導入可能なSciPy

SciPyは新しい版ほど古いPythonのサポートを外します。SciPy 1.18.0からはPython 3.12以上が必要です。pip install scipy は、そのPythonで動く範囲の最新版を選ぶため、Python 3.11ではエラーにならずに1.17.1が入ります。uvの依存解決で、Pythonの版ごとに入る版を確かめました(2026年10月27日時点)。

Python 入るSciPy 入るNumPy
3.12以上 1.18.1 2.5.4
3.11 1.17.1 2.4.6
3.10 1.15.3 2.2.6
3.9 1.13.1 2.0.2

チームで同じ結果を出したいなら、Pythonの版をそろえるのが先です。記事やサンプルの関数が見つからないときも、まず scipy.__version__ を見て、古い版が入っていないかを確かめます。

pip install scipy が失敗するときの対処

「No matching distribution found」:Pythonのバージョン要件不一致

版を指定して入れようとして、Pythonがその版の要件を満たしていないと、次のように弾かれます。Docker の python:3.11-slim で pip install scipy==1.18.1 を実行したときの出力(抜粋)です。

ERROR: Ignored the following versions that require a different python version: 1.18.0 Requires-Python >=3.12; ... 1.18.1 Requires-Python >=3.12; ...
ERROR: Could not find a version that satisfies the requirement scipy==1.18.1 (from versions: ... 1.17.0, 1.17.1)
ERROR: No matching distribution found for scipy==1.18.1

「Requires-Python >=3.12」が原因そのものです。Python 3.12以上の環境を作り直すか、そのPythonで入る1.17.1に指定を下げます。requirements.txtに他の環境で固定した版が書かれているときに起きやすいエラーです。

「Unknown compiler(s)」:ソースビルド時のコンパイラ不足

pipは、使っている環境向けのwheelがPyPIに無いと、ソース配布物(scipy-1.18.1.tar.gz)をダウンロードして手元でビルドしようとします。SciPyのビルドにはC・C++・Fortranのコンパイラと、BLAS/LAPACKのライブラリが必要です(SciPy公式のビルド手順)。コンパイラの無い環境では、メタデータの準備の段階で止まります。Docker の python:3.12-slim でソースビルドを強制したときの出力(抜粋)です。

Project name: scipy
Project version: 1.18.1

../meson.build:1:0: ERROR: Unknown compiler(s): [['cc'], ['gcc'], ['clang'], ['nvc'], ['pgcc'], ['icc'], ['icx']]
...
error: metadata-generation-failed

このエラーが出たら、コンパイラを入れる前に、なぜwheelが選ばれなかったかを確かめます。SciPy 1.18.1のwheelがあるのは、Python 3.12〜3.15の、Windows(x64・ARM64)、macOS(Intel・Apple Silicon)、Linux(x86_64・aarch64のglibc版とmusl版)です。次の環境はwheelの対象外です。

  • Windowsの32ビット版Python(wheelはwin_amd64とwin_arm64だけ)
  • glibcが2.27より古いLinux(Linux向けwheelのタグがmanylinux_2_27・manylinux_2_28)
  • wheelが公開される前の新しいPython

対処は、64ビット版のPythonに入れ直す、wheelのあるPythonの版に合わせる、condaのconda-forgeから入れる、の順に試します。ソースビルドを選ぶのは、SciPyの開発に参加する場合か、wheelもconda-forgeのパッケージも無い環境に限ります。なお、SciPy 1.18.0ではFortranコンパイラなしでビルドする選択肢が試験的に入りましたが、リリースノートの位置づけは開発者の試験用途です(SciPy 1.18.0リリースノート)。

SciPyの使い方:目的別のコード例

以下はPython 3.12.13、SciPy 1.18.1、NumPy 2.5.4で実行したコードと出力です。乱数を使う例は np.random.default_rng(0) で固定しています。

最適化:minimize・curve_fit・linprog

minimize は関数の最小値を探します。methodを省略すると、制約(constraints)があればSLSQP、範囲(bounds)だけならL-BFGS-B、どちらも無ければBFGSが選ばれます(SciPy 1.18.0のminimizeのソース)。curve_fit はデータに式のパラメータを合わせ、linprog は線形計画問題を解きます。

import numpy as np
from scipy import optimize

# Rosenbrock関数の最小化(5変数)
r = optimize.minimize(optimize.rosen, x0=[1.3, 0.7, 0.8, 1.9, 1.2])
print(r.success, np.round(r.x, 4), r.nit)   # True [1. 1. 1. 1. 1.] 25

# 指数減衰 a*exp(-b*t)+c をノイズ入りデータに当てはめる
rng = np.random.default_rng(0)
t = np.linspace(0, 4, 50)
y = 2.5 * np.exp(-1.3 * t) + 0.5 + rng.normal(0, 0.05, t.size)
p, cov = optimize.curve_fit(lambda t, a, b, c: a * np.exp(-b * t) + c, t, y, p0=[1, 1, 0])
print(np.round(p, 3))                        # [2.504 1.384 0.534]

# 3x+2y を最大化(linprogは最小化なので符号を反転)
res = optimize.linprog(c=[-3, -2], A_ub=[[1, 1], [1, 3]], b_ub=[4, 6],
                       bounds=[(0, None), (0, None)])
print(res.x, res.fun)                        # [4. 0.] -12.0
print(res.message)  # Optimization terminated successfully. (HiGHS Status 7: Optimal)

curve_fit は真の値(2.5、1.3、0.5)に近い2.504、1.384、0.534を返しました。linprog の既定のmethodは’highs’で、HiGHSの2つのソルバーから自動で選びます(linprogの公式リファレンス)。制約付き最適化の手法の選び方や、整数計画のmilpはscipy.optimizeの使い方|minimize・least_squares・milpで扱っています。

数値積分と微分方程式:quad・solve_ivp

quad は定積分を、solve_ivp は常微分方程式の初期値問題を解きます。solve_ivp は既定の許容誤差が粗い点に注意が要ります。

import numpy as np
from scipy import integrate

v, err = integrate.quad(lambda x: np.exp(-x ** 2), -np.inf, np.inf)
print(v, np.sqrt(np.pi))   # 1.7724538509055159 1.7724538509055159

# dy/dt = -0.5y, y(0)=2 の厳密解は 2*exp(-0.5t)
f = lambda t, y: -0.5 * y
exact = 2 * np.exp(-0.5 * np.array([2, 4, 10]))
s1 = integrate.solve_ivp(f, [0, 10], [2.0], t_eval=[2, 4, 10])
s2 = integrate.solve_ivp(f, [0, 10], [2.0], t_eval=[2, 4, 10], rtol=1e-8, atol=1e-10)
print(abs(s1.y[0] - exact).max())   # 0.000418...
print(abs(s2.y[0] - exact).max())   # 1.55e-09

既定のままだと厳密解との差が最大0.00042(t=2で0.73534に対し厳密解0.73576)でした。rtol=1e-8 と atol=1e-10 を指定すると差は1.6×10⁻⁹まで縮みます。必要な精度は方程式と用途によって異なります。描画用でも既定値で十分とは限らないため、許容誤差を小さくして結果の変化を確認します。

統計:t検定と確率分布

scipy.stats には100を超える確率分布と検定がまとまっています。2群の平均の差を調べる ttest_ind は、既定が等分散を仮定するStudentのt検定です。分散が等しいと言えないデータなら equal_var=False でWelchのt検定にします。

import numpy as np
from scipy import stats

rng = np.random.default_rng(0)
_ = rng.normal(0, 0.05, 50)          # 上の例と同じ乱数列にそろえるための読み捨て
a = rng.normal(50, 5, 30)
b = rng.normal(53, 8, 30)
print(stats.ttest_ind(a, b))                   # df=58.0, pvalue=0.3907
print(stats.ttest_ind(a, b, equal_var=False))  # df=50.79, pvalue=0.3912
print(stats.norm.ppf(0.975))                   # 1.959963984540054

自由度がStudentでは58、Welchでは50.79になり、p値も変わります。今回の例では差は小さいですが、群の大きさと分散の両方が違うと結論が分かれることがあります。検定の選び方とp値の読み方は有意差検定とは?有意差・p値の意味と検定の種類で説明しています。

信号処理:ローパスフィルタによる高周波ノイズの低減

scipy.signal でフィルタを設計し、波形にかけます。5Hzの波に120Hzのノイズを足した信号に、30Hzのバターワース・ローパスフィルタ(4次)をかけました。

import numpy as np
from scipy import signal

fs = 1000                                   # サンプリング周波数 [Hz]
t = np.arange(0, 1, 1 / fs)
x = np.sin(2 * np.pi * 5 * t) + 0.5 * np.sin(2 * np.pi * 120 * t)
sos = signal.butter(4, 30, btype="low", fs=fs, output="sos")
y = signal.sosfiltfilt(sos, x)              # 前後2回かけて位相のずれを打ち消す
amplitude = 2 * np.abs(np.fft.rfft(y)) / y.size
print(amplitude[5], amplitude[120])  # 約1.00015、約0.000712

FFTで振幅を測ると、5Hz成分は1.0から約1.00015へわずかに変わり、120Hz成分は0.5から約0.000712に下がりました。output="sos"(2次セクション形式)で設計しておくと、次数を上げても係数の丸め誤差で不安定になりにくくなります。

近傍探索:KDTree

多数の点から近い点を探すなら scipy.spatial.KDTree を使います。木によって探索候補を絞れますが、効率は次元数や点の分布に左右されます。KDTreeの公式リファレンスも、20次元でもすでに高次元で、総当たりより大幅に速くなるとは期待しないよう説明しています。

import numpy as np
from scipy.spatial import KDTree

rng = np.random.default_rng(1)
pts = rng.random((10000, 2))           # 1万点
tree = KDTree(pts)
dist, idx = tree.query([[0.5, 0.5]], k=3)   # (0.5, 0.5) に近い3点
print(dist, idx)   # [[0.00558033 0.00940872 0.01114484]] [[2186 1019 4630]]

SciPyで書いた計算を業務システムに組み込む段階では、入力データの受け渡しや実行の監視も含めた設計が要ります。そうした開発はフルスクラッチ開発として承っています。

バージョンの確認と非推奨モジュールの扱い

入っているSciPyの版は scipy.__version__ で、ビルドに使われたコンパイラやBLAS/LAPACKの種類は scipy.show_config() で確認できます。

import scipy
print(scipy.__version__)   # 1.18.1
scipy.show_config()        # コンパイラ、BLAS/LAPACK などのビルド情報

古い記事のコードが動かないときは、関数や引数の削除が原因のことがあります。SciPy 1.18.0では次の変更がありました(SciPy 1.18.0リリースノート)。

  • fmin_l_bfgs_b の iprint・disp、nnls の atol、sqrtm・logm・signm の disp と sqrtm の blocksize が削除された
  • FFTの内部実装がpocketfftから後継のducc0.fftに替わった

scipy.odr は1.17.0で非推奨になり、1.19.0で削除される予定です。scipy.odrの公式リファレンスは移行先としてPyPIの odrpack を案内しています。直交距離回帰を使っているコードは、1.19.0が出る前に移しておきます。

よくある質問

SciPyの読み方は?

「サイパイ」です。SciPy公式のREADMEにpronounced "Sigh Pie"と書かれています。

SciPyとNumPyの違いは?

NumPyは配列と基本演算、SciPyはその配列に対する最適化・積分・統計・信号処理・補間などの手法を提供します。SciPyはNumPyに依存しているので、SciPyを入れるとNumPyも一緒に入ります。

import scipy だけでサブパッケージは使えますか?

使えます。SciPy 1.9.0からサブパッケージは参照した時点で読み込まれるようになり、import scipy のあとに scipy.optimize.minimize_scalar(...) と書いても動きます。1.9.0のリリースノートは当初この書き方を対話的な利用向けとしていましたが、現在のSciPy公式APIリファレンスの「Guidelines for importing functions from SciPy」は、import scipy して scipy.optimize.curve_fit(...) と書く形を最初に示し、from scipy import optimize も同等の書き方として載せています。scipy.io は標準ライブラリの io と名前がぶつかるので、import scipy の形が勧められています。

Python 3.11で最新版のSciPyは使えますか?

使えません。SciPy 1.18.0以降はPython 3.12以上が必要で、Python 3.11で pip install scipy を実行すると1.17.1が入ります。1.18の機能が要るならPythonを3.12以上にします。

SciPyのライセンスは?商用利用できますか?

BSD 3-Clauseライセンスです。条件(著作権表示とライセンス文の保持など)を満たせば、改変の有無を問わずソースとバイナリの再配布・利用が認められており、商用のソフトウェアにも組み込めます。

関連記事

お気に入りに入れた記事の一覧

この記事は以下の記事からリンクされています

資料請求

今日のトレンド記事 直近 24 時間で、いつもより多く読まれている記事

  1. 2026.10.27 テックブログ Brotli 脆弱性:CVE-2026-111497の影響確認とNode.js・Python・.NETの更新手順
  2. 2025.02.27 コラム トラッキングビーコン(Webビーコン)とは?仕組み・用途・確認と対策を徹底解説
  3. 2026.10.27 テックブログ Joshin(ジョーシン)不正アクセス:最大600万件の対象とサブスク初期パスワードの対処
  4. 2026.10.28 テックブログ リンツ不正アクセス:314万件の対象確認とパスワード強制リセット後の対処
  5. 2026.10.23 テックブログ Renta!はいつ再開?不正アクセスでメールアドレス等が流出したおそれ・再開時のパスワード再設定と運営側の対応

RELATED POSTS 関連記事

目次