NumPy Linspace:Pythonで等間隔配列を作成する方法
Updated on
等間隔の数列を生成することは、開始値、終了値、個数を正確に制御する必要が出てくるまでは簡単に思えます。Pythonの組み込み関数range()は整数しか扱えず、numpy.arange()でさえ浮動小数点のステップサイズが丸め誤差を蓄積すると、予期しない結果を生むことがあります。関数をプロットして、ギザギザした曲線になったり、最後のx値が欠けたりした経験があるなら、まさにこの問題に遭遇しています。numpy.linspace()はこれを解決するために存在します:2つの端点間に何個の点が欲しいかを指定するだけで、NumPyが正確な間隔を計算してくれます。
このガイドでは、np.linspace()の完全なAPIを学び、np.arange()との比較を見て、滑らかな曲線の描画から多次元グリッドの構築まで、実際のユースケースを順に確認していきます。すべてのコード例はコピー&ペーストですぐに実行でき、出力結果も表示されています。
np.linspace()は何をするのか?
numpy.linspace()は、指定された区間にわたって等間隔の数値配列を返します。重要なアイデアは、ステップサイズではなくサンプル数を定義するということです。
完全なシグネチャ
numpy.linspace(start, stop, num=50, endpoint=True, retstep=False, dtype=None, axis=0)| パラメータ | 型 | デフォルト | 説明 |
|---|---|---|---|
start | floatまたはarray-like | 必須 | 区間の開始 |
stop | floatまたはarray-like | 必須 | 区間の終了 |
num | int | 50 | 生成するサンプル数 |
endpoint | bool | True | 出力にstopを含めるかどうか |
retstep | bool | False | Trueの場合、ステップサイズも返す |
dtype | dtype | None | 出力配列のデータ型(Noneの場合は推論) |
axis | int | 0 | サンプルを格納する軸(start/stopが配列の場合に関連) |
基本的な例
import numpy as np
arr = np.linspace(0, 1, 5)
print(arr)
# Output: [0. 0.25 0.5 0.75 1. ]NumPyは区間[0, 1]を4つの等しい間隔(要求された5点より1つ少ない)に分割し、両端点を含む5つすべての境界値を返します。
numでポイント数を制御する
numパラメータは、返される配列に含まれる値の数を決定します。デフォルトは50なので、np.linspace(0, 10)を呼び出すと、明示的に指定しなくても50個の値が返されます。
import numpy as np
# 0から10の間に3点
print(np.linspace(0, 10, num=3))
# Output: [ 0. 5. 10.]
# -1から1の間に6点
print(np.linspace(-1, 1, num=6))
# Output: [-1. -0.6 -0.2 0.2 0.6 1. ]よくある間違いはnum=1を設定することです。この場合、startの値のみが返されます。
import numpy as np
print(np.linspace(0, 10, num=1))
# Output: [0.]endpointパラメータ:終了値の包含と除外
デフォルトではendpoint=Trueで、stop値が配列の最後の要素になります。endpoint=Falseに設定すると、終了値は除外され、間隔が変わります。
import numpy as np
with_endpoint = np.linspace(0, 1, 5, endpoint=True)
print("endpoint=True: ", with_endpoint)
# Output: endpoint=True: [0. 0.25 0.5 0.75 1. ]
without_endpoint = np.linspace(0, 1, 5, endpoint=False)
print("endpoint=False:", without_endpoint)
# Output: endpoint=False: [0. 0.2 0.4 0.6 0.8]| 設定 | ステップの計算式 | 最後の値 |
|---|---|---|
endpoint=True | (stop - start) / (num - 1) | 正確にstop |
endpoint=False | (stop - start) / num | stopの1ステップ手前 |
endpoint=Falseはいつ便利でしょうか?古典的な例は、離散フーリエ変換用の角度を生成する場合です。[0, 2*pi)にN個の点が必要で、開始角度を繰り返したくない場合に使います。
import numpy as np
N = 8
angles = np.linspace(0, 2 * np.pi, N, endpoint=False)
print(np.round(angles, 4))
# Output: [0. 0.7854 1.5708 2.3562 3.1416 3.927 4.7124 5.4978]retstepでステップサイズを取得する
retstep=Trueの場合、np.linspace()はタプルを返します:配列と計算されたステップサイズです。後の計算でステップサイズが必要だが自分で計算したくない場合に便利です。
import numpy as np
values, step = np.linspace(0, 10, num=5, retstep=True)
print("Values:", values)
print("Step: ", step)
# Output:
# Values: [ 0. 2.5 5. 7.5 10. ]
# Step: 2.5ステップサイズは数値微分、積分、またはグリッドが期待する解像度を持っているかの検証に使用できます。
import numpy as np
x, dx = np.linspace(0, np.pi, 1000, retstep=True)
# Approximate integral of sin(x) from 0 to pi using the trapezoidal rule
integral = np.trapz(np.sin(x), dx=dx)
print(f"Integral of sin(x) over [0, pi]: {integral:.6f}")
# Output: Integral of sin(x) over [0, pi]: 2.000000np.linspace() vs np.arange():どちらを使うべきか
どちらの関数も数列を作成しますが、根本的に異なります:linspaceは個数を指定し、arangeはステップサイズを指定します。
| 特徴 | np.linspace() | np.arange() |
|---|---|---|
| 指定するもの | ポイント数(num) | ステップサイズ(step) |
| 端点を含む? | デフォルトでYes | 含まない(排他的stop) |
| 浮動小数点ステップの精度 | 正確(区間を分割) | 丸め誤差が蓄積する可能性 |
| 典型的な用途 | プロット、補間 | 整数範囲、イテレーション |
| ステップサイズを返す? | retstep=Trueで可能 | いいえ(すでに知っている) |
arangeの浮動小数点の落とし穴
import numpy as np
# arange can produce unexpected element counts with float steps
arr = np.arange(0, 1, 0.1)
print(len(arr), arr)
# Output: 10 [0. 0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8 0.9]
# Slightly different bounds can cause an extra element
arr2 = np.arange(0, 1.0 + 1e-15, 0.1)
print(len(arr2))
# Output: 11linspaceを使えば、常に要求した正確な数の要素が得られます。浮動小数点の区間を扱う場合は、特定のステップサイズと整数に適した境界が本当に必要でない限り、linspaceを選択してください。
実用的なユースケース
1. 滑らかな曲線のプロット
np.linspace()の最も一般的な用途は、数学関数をプロットするためのx値の生成です。ポイントが多いほど、より滑らかな曲線になります。
import numpy as np
import matplotlib.pyplot as plt
x = np.linspace(-2 * np.pi, 2 * np.pi, 300)
y = np.sin(x) / x # sinc-like function (warning: division by zero at x=0)
# Handle division by zero
y = np.where(np.isclose(x, 0), 1.0, np.sin(x) / x)
plt.figure(figsize=(8, 4))
plt.plot(x, y, linewidth=1.5)
plt.title("sinc-like function: sin(x)/x")
plt.xlabel("x")
plt.ylabel("y")
plt.grid(True, alpha=0.3)
plt.tight_layout()
plt.savefig("sinc_plot.png", dpi=100)
plt.show()2. 信号処理:時間軸の生成
信号のシミュレーションや解析では、既知のサンプリングレートを持つ時間ベクトルが必要です。linspaceを使えば簡単に作成できます。
import numpy as np
duration = 1.0 # seconds
sample_rate = 44100 # Hz (CD quality)
num_samples = int(duration * sample_rate)
t = np.linspace(0, duration, num_samples, endpoint=False)
# Generate a 440 Hz sine wave (concert A)
frequency = 440
signal = np.sin(2 * np.pi * frequency * t)
print(f"Time array shape: {t.shape}")
print(f"First 5 time values: {t[:5]}")
print(f"First 5 signal values: {np.round(signal[:5], 6)}")
# Output:
# Time array shape: (44100,)
# First 5 time values: [0.00000000e+00 2.26757370e-05 4.53514739e-05 6.80272109e-05 9.07029478e-05]
# First 5 signal values: [0. 0.062648 0.125178 0.187474 0.24942 ]ここでendpoint=Falseが使われているのは、信号が周期的だからです:t = 1.0のサンプルはt = 0.0のサンプルと重複してしまいます。
3. カラーグラデーションの作成
linspaceは、カスタムカラーマップを構築する際に色値間を補間するのに便利です。
import numpy as np
# Interpolate between blue (0, 0, 255) and red (255, 0, 0) in 5 steps
steps = 5
r = np.linspace(0, 255, steps).astype(int)
g = np.zeros(steps, dtype=int)
b = np.linspace(255, 0, steps).astype(int)
colors = np.column_stack([r, g, b])
for i, c in enumerate(colors):
print(f"Step {i}: RGB({c[0]:3d}, {c[1]:3d}, {c[2]:3d})")
# Output:
# Step 0: RGB( 0, 0, 255)
# Step 1: RGB( 63, 0, 191)
# Step 2: RGB(127, 0, 127)
# Step 3: RGB(191, 0, 63)
# Step 4: RGB(255, 0, 0)linspaceとmeshgridによる多次元グリッド
2Dまたは3Dの計算(ヒートマップ、サーフェスプロット、等高線プロット)では、np.linspace()とnp.meshgrid()を組み合わせます。
import numpy as np
x = np.linspace(-3, 3, 100)
y = np.linspace(-3, 3, 100)
X, Y = np.meshgrid(x, y)
# Compute a 2D Gaussian
Z = np.exp(-(X**2 + Y**2))
print(f"X shape: {X.shape}")
print(f"Z min: {Z.min():.6f}, Z max: {Z.max():.6f}")
# Output:
# X shape: (100, 100)
# Z min: 0.000001, Z max: 1.000000import numpy as np
import matplotlib.pyplot as plt
x = np.linspace(-3, 3, 200)
y = np.linspace(-3, 3, 200)
X, Y = np.meshgrid(x, y)
Z = np.exp(-(X**2 + Y**2))
plt.figure(figsize=(6, 5))
plt.contourf(X, Y, Z, levels=20, cmap="viridis")
plt.colorbar(label="Amplitude")
plt.title("2D Gaussian via linspace + meshgrid")
plt.xlabel("x")
plt.ylabel("y")
plt.tight_layout()
plt.savefig("gaussian_contour.png", dpi=100)
plt.show()このパターンは任意の次元に拡張できます。3Dグリッドの場合は、3つ目のlinspace呼び出しを追加してnp.meshgrid(x, y, z)を使用します。
dtypeパラメータ
デフォルトでは、np.linspace()はfloat64の値を返します。dtypeパラメータでこれを変更できますが、整数型は計算された値を切り捨てることに注意してください。
import numpy as np
# Float64 (default)
print(np.linspace(0, 5, 6).dtype)
# Output: float64
# Explicit float32 for memory savings
arr32 = np.linspace(0, 1, 5, dtype=np.float32)
print(arr32, arr32.dtype)
# Output: [0. 0.25 0.5 0.75 1. ] float32
# Integer dtype truncates values
arr_int = np.linspace(0, 10, 5, dtype=int)
print(arr_int)
# Output: [ 0 2 5 7 10]整数dtypeを使用すると、小数部分は単純に切り捨てられ(floor動作)、不均等な間隔の結果を生む可能性があります。変換する特別な理由がない限り、float型を使い続けてください。
よくあるパターン:関数プロット用のX値生成
繰り返し使うパターンの簡潔なリファレンスです。
パターン1:標準的な関数プロット
import numpy as np
import matplotlib.pyplot as plt
x = np.linspace(0, 10, 500)
plt.plot(x, np.sin(x), label="sin(x)")
plt.plot(x, np.cos(x), label="cos(x)")
plt.legend()
plt.grid(True, alpha=0.3)
plt.tight_layout()
plt.show()パターン2:パラメトリック曲線
import numpy as np
import matplotlib.pyplot as plt
t = np.linspace(0, 2 * np.pi, 1000)
x = 16 * np.sin(t)**3
y = 13 * np.cos(t) - 5 * np.cos(2*t) - 2 * np.cos(3*t) - np.cos(4*t)
plt.figure(figsize=(5, 5))
plt.plot(x, y, color="red")
plt.title("Heart Curve")
plt.axis("equal")
plt.grid(True, alpha=0.3)
plt.tight_layout()
plt.show()パターン3:範囲上での多項式の評価
import numpy as np
coefficients = [1, -3, 2] # x^2 - 3x + 2
x = np.linspace(-1, 4, 6)
y = np.polyval(coefficients, x)
for xi, yi in zip(x, y):
print(f"x={xi:5.2f} -> y={yi:5.2f}")
# Output:
# x=-1.00 -> y= 6.00
# x= 0.00 -> y= 2.00
# x= 1.00 -> y= 0.00
# x= 2.00 -> y= 0.00
# x= 3.00 -> y= 2.00
# x= 4.00 -> y= 6.00Linspaceで生成したデータをPyGWalkerで可視化する
np.linspace()で作成した配列を扱う際、結果のデータをインタラクティブに探索したいことがよくあります。軸の調整、範囲のフィルタリング、複数系列の比較を毎回プロットコードを書き直さずに行いたいものです。PyGWalker (opens in a new tab)は、任意のPandas DataFrameをTableauのようなインタラクティブな可視化インターフェースに変換するオープンソースPythonライブラリで、Jupyter Notebook内で直接使用できます。
linspaceで生成したデータをPyGWalkerと組み合わせてインタラクティブに探索する方法は次のとおりです:
import numpy as np
import pandas as pd
import pygwalker as pyg
# Generate data using linspace
x = np.linspace(0, 4 * np.pi, 200)
df = pd.DataFrame({
"x": x,
"sin": np.sin(x),
"cos": np.cos(x),
"damped_sin": np.exp(-0.1 * x) * np.sin(x),
})
# Launch interactive visualization in Jupyter
walker = pyg.walk(df)PyGWalkerを開くと、xをx軸にドラッグし、sinとdamped_sinをy軸にドロップして、波形を即座に比較できます。追加のコードを書くことなく、折れ線グラフ、散布図、棒グラフを切り替えることができます。これは、linspaceで異なるパラメータ範囲にわたってデータを生成し、最終的なプロットにコミットする前に視覚的に挙動を確認したい場合に特に便利です。
よくある質問
np.linspaceとnp.arangeの違いは何ですか?
np.linspace()は開始値、終了値、そして必要なポイント数を受け取ります。np.arange()は開始値、終了値、そしてステップサイズを受け取ります。ポイント数が重要な場合(プロット、補間)はlinspaceを使いましょう。値間の正確なステップが重要な場合(整数列、ループ)はarangeを使いましょう。
np.linspaceはデフォルトで端点を含みますか?
はい。デフォルトでendpoint=Trueなので、stop値が最後の要素として含まれます。周期的な信号やフーリエ変換で端点を除外するにはendpoint=Falseに設定してください。
np.linspaceからステップサイズを取得するには?
retstep=Trueを渡すと、(配列, ステップサイズ)のタプルが返されます。例:values, step = np.linspace(0, 10, 100, retstep=True)。
np.linspaceで整数を生成できますか?
dtype=intを渡すことはできますが、値は切り捨てられ(四捨五入ではなく)、多くの場合不均等な間隔になります。等間隔の整数が必要な場合は、np.arange()の方が通常は良い選択です。
滑らかなプロットには何ポイント使うべきですか?
ほとんどの2D関数プロットでは、200から500ポイントで視覚的に滑らかな曲線が得られます。高周波関数や出版品質の図には、1000ポイントが安全な選択です。ポイント数が増えるとメモリ使用量とレンダリング時間が増加するため、滑らかさとパフォーマンスのバランスを取りましょう。
まとめ
numpy.linspace()が最もよく使われるNumPy関数の1つである理由は明確です:2つの端点間に生成する等間隔の値の数を正確に制御できるからです。np.arange()とは異なり、浮動小数点の丸めによって余分な要素が追加されたり要素が欠けたりすることがありません。endpoint、retstep、dtypeパラメータにより、簡単なプロットから信号処理パイプラインまで、あらゆる場面で細かな制御が可能です。
重要なポイント:
numを使って出力値の正確な数を設定する。- 終了値が開始値と重複する周期データには
endpoint=Falseを設定する。 - 後続の計算にステップサイズが必要な場合は
retstep=Trueを使用する。 - 浮動小数点の区間では
arangeよりもlinspaceを優先する。 - 多次元グリッドには
linspaceとmeshgridを組み合わせる。
これらのパターンをツールキットに加えれば、Pythonでのプロット、シミュレーション、補間、科学計算のための数値列を自信を持って生成できます。