NumPy arange・linspaceの使い方完全マスター!連番・等差数列生成の決定版
NumPyで数値の配列を生成する際、最も頻繁に使用されるのがarange()とlinspace()関数です。本記事では、これらの関数の違いと使い分け、実践的な活用方法を豊富なサンプルコードとともに詳しく解説します。
arangeとlinspaceの基本的な違い
numpy.arange(): ステップ幅を指定して等差数列を生成numpy.linspace(): 要素数を指定して等間隔の数列を生成
import numpy as np
# arange: ステップ0.5で0から3未満
arr1 = np.arange(0, 3, 0.5)
print("arange:", arr1) # [0. 0.5 1. 1.5 2. 2.5]
# linspace: 0から3まで7個の等間隔点
arr2 = np.linspace(0, 3, 7)
print("linspace:", arr2) # [0. 0.5 1. 1.5 2. 2.5 3. ]
1. numpy.arange() – ステップ指定の連番生成
1-1. 基本的な使用方法
# 整数の連番(0から9まで)
arr = np.arange(10)
print(arr) # [0 1 2 3 4 5 6 7 8 9]
# 開始値と終了値を指定
arr = np.arange(2, 8)
print(arr) # [2 3 4 5 6 7]
# ステップ幅を指定
arr = np.arange(0, 10, 2)
print(arr) # [0 2 4 6 8]
1-2. 浮動小数点数での使用
# 小数のステップ
arr = np.arange(0, 2, 0.3)
print(arr) # [0. 0.3 0.6 0.9 1.2 1.5 1.8]
# 負のステップ(降順)
arr = np.arange(5, 0, -1)
print(arr) # [5 4 3 2 1]
# 小数での降順
arr = np.arange(1, 0, -0.2)
print(arr) # [1. 0.8 0.6 0.4 0.2]
1-3. データ型の指定
# 整数型を明示的に指定
arr = np.arange(5, dtype=int)
print(arr, arr.dtype) # [0 1 2 3 4] int64
# 浮動小数点型を指定
arr = np.arange(5, dtype=float)
print(arr, arr.dtype) # [0. 1. 2. 3. 4.] float64
# 複素数型
arr = np.arange(3, dtype=complex)
print(arr) # [0.+0.j 1.+0.j 2.+0.j]
2. numpy.linspace() – 要素数指定の等間隔生成
2-1. 基本的な使用方法
# 0から10まで11個の等間隔点
arr = np.linspace(0, 10, 11)
print(arr) # [ 0. 1. 2. 3. 4. 5. 6. 7. 8. 9. 10.]
# πの分割
arr = np.linspace(0, np.pi, 5)
print(arr) # [0. 0.78539816 1.57079633 2.35619449 3.14159265]
# より細かい分割
arr = np.linspace(-1, 1, 9)
print(arr) # [-1. -0.75 -0.5 -0.25 0. 0.25 0.5 0.75 1. ]
2-2. endpoint パラメータ
# 終点を含む(デフォルト)
arr1 = np.linspace(0, 1, 5, endpoint=True)
print("終点含む:", arr1) # [0. 0.25 0.5 0.75 1. ]
# 終点を含まない
arr2 = np.linspace(0, 1, 5, endpoint=False)
print("終点除く:", arr2) # [0. 0.2 0.4 0.6 0.8]
2-3. retstep パラメータ
# ステップサイズも取得
arr, step = np.linspace(0, 10, 21, retstep=True)
print(f"配列の長さ: {len(arr)}") # 21
print(f"ステップサイズ: {step}") # 0.5
print(f"最初の3要素: {arr[:3]}") # [0. 0.5 1. ]
3. 実践的な使い分けガイド
3-1. いつarangeを使うか
# インデックスとして使用
indices = np.arange(len(data)) # データ長に応じたインデックス
# 固定ステップでの繰り返し処理
for i in np.arange(0, 100, 5): # 5ステップごと
print(f"処理 {i}")
# 時系列データの生成(秒単位)
time_seconds = np.arange(0, 60, 0.1) # 0.1秒間隔で1分間
3-2. いつlinspaceを使うか
# グラフのx軸生成
x = np.linspace(-np.pi, np.pi, 100) # 滑らかな曲線用
y = np.sin(x)
# 分析範囲の等分割
analysis_points = np.linspace(min_val, max_val, 50)
# パラメータスイープ
learning_rates = np.linspace(0.001, 0.1, 20) # 20個の学習率
4. 高度な活用例
4-1. 2次元グリッドの生成
# meshgridと組み合わせて2Dグリッド作成
x = np.linspace(-2, 2, 5)
y = np.linspace(-1, 1, 3)
X, Y = np.meshgrid(x, y)
print("X座標:")
print(X)
print("Y座標:")
print(Y)
4-2. 対数スケールとの組み合わせ
# 対数スケールでの等間隔
log_points = np.logspace(0, 2, 5) # 10^0 から 10^2 まで
print("対数等間隔:", log_points) # [ 1. 3.16227766 10. 31.6227766 100. ]
# linspaceで対数軸作成
log_x = np.linspace(np.log10(1), np.log10(100), 5)
linear_equiv = 10 ** log_x
print("同等結果:", linear_equiv)
4-3. 関数の数値積分での活用
def simpson_integration(func, a, b, n):
"""シンプソン法での数値積分"""
if n % 2 == 1:
n += 1 # 偶数に調整
x = np.linspace(a, b, n+1)
y = func(x)
# シンプソン法の重み
weights = np.ones(n+1)
weights[1::2] = 4 # 奇数インデックス
weights[2::2] = 2 # 偶数インデックス(端点除く)
return (b - a) / (3 * n) * np.sum(weights * y)
# 使用例: sin(x)を0からπまで積分
result = simpson_integration(np.sin, 0, np.pi, 100)
print(f"∫sin(x)dx = {result:.6f}") # 理論値は2
5. パフォーマンス比較と最適化
5-1. 速度比較
import time
# 大規模配列での速度比較
n = 1000000
# arangeの速度
start = time.time()
arr1 = np.arange(n)
time1 = time.time() - start
# linspaceの速度
start = time.time()
arr2 = np.linspace(0, n-1, n)
time2 = time.time() - start
print(f"arange: {time1:.6f}秒")
print(f"linspace: {time2:.6f}秒")
print(f"速度比: {time2/time1:.2f}倍")
5-2. メモリ効率的な生成
# 大規模配列でのメモリ効率
def memory_efficient_range(start, stop, step, chunk_size=10000):
"""メモリ効率的な大規模配列処理"""
current = start
while current < stop:
end = min(current + chunk_size * step, stop)
chunk = np.arange(current, end, step)
yield chunk
current = end
# 使用例
total_elements = 0
for chunk in memory_efficient_range(0, 1000000, 1, 50000):
total_elements += len(chunk)
# chunk単位での処理
print(f"処理した要素数: {total_elements}")
6. よくある問題と解決方法
6-1. 浮動小数点の精度問題
# 問題のあるコード
problematic = np.arange(0, 1, 0.1)
print("arange結果:", len(problematic)) # 期待値10だが実際は10
# 解決策1: linspaceを使用
solution1 = np.linspace(0, 1, 11)[:-1] # 終点を除外
print("linspace解決:", len(solution1))
# 解決策2: 整数で計算後に変換
solution2 = np.arange(0, 10) * 0.1
print("整数変換解決:", len(solution2))
6-2. 空配列の回避
def safe_arange(start, stop, step):
"""安全なarange(空配列チェック付き)"""
if (step > 0 and start >= stop) or (step < 0 and start <= stop):
return np.array([])
return np.arange(start, stop, step)
# テスト
result1 = safe_arange(5, 2, 1) # 空配列
result2 = safe_arange(2, 5, 1) # 正常
print("空配列回避1:", result1)
print("正常動作:", result2)
6-3. 型変換の問題
# 意図しない型変換の回避
def typed_arange(start, stop, step, dtype=None):
"""型を保持するarange"""
result = np.arange(start, stop, step)
if dtype is not None:
result = result.astype(dtype)
return result
# 使用例
int_range = typed_arange(0, 10, 1, dtype=int)
float_range = typed_arange(0, 10, 1, dtype=float)
print("整数型:", int_range.dtype)
print("浮動小数点型:", float_range.dtype)
7. 実用的なレシピ集
7-1. 時系列データの生成
def generate_time_series(start_date, periods, freq='D'):
"""時系列インデックスの生成"""
if freq == 'D': # 日次
days = np.arange(periods)
return [start_date + pd.Timedelta(days=d) for d in days]
elif freq == 'H': # 時間次
hours = np.arange(periods)
return [start_date + pd.Timedelta(hours=h) for h in hours]
# NumPyのみでの簡易版
def simple_time_range(hours):
"""時間の配列を生成(時間単位)"""
return np.arange(0, hours, 0.5) # 30分間隔
time_points = simple_time_range(24) # 24時間分
print(f"時間点数: {len(time_points)}")
7-2. グラデーション配列の生成
def create_gradient(start_color, end_color, steps):
"""カラーグラデーション用の値生成"""
r = np.linspace(start_color[0], end_color[0], steps)
g = np.linspace(start_color[1], end_color[1], steps)
b = np.linspace(start_color[2], end_color[2], steps)
return np.column_stack([r, g, b])
# 赤から青へのグラデーション
gradient = create_gradient([255, 0, 0], [0, 0, 255], 10)
print("グラデーション(最初の3色):")
print(gradient[:3].astype(int))
7-3. サンプリング頻度の計算
def calculate_sampling_params(signal_freq, duration, min_points=100):
"""信号解析用のサンプリングパラメータ計算"""
# ナイキスト周波数の2倍以上でサンプリング
min_sampling_freq = 2.1 * signal_freq
# 最小点数も考慮
required_freq = max(min_sampling_freq, min_points / duration)
# 実際のサンプリング点
num_points = int(required_freq * duration)
actual_freq = num_points / duration
return {
'num_points': num_points,
'sampling_freq': actual_freq,
'time_array': np.linspace(0, duration, num_points)
}
# 100Hz信号を1秒間サンプリング
params = calculate_sampling_params(100, 1.0)
print(f"サンプリング点数: {params['num_points']}")
print(f"サンプリング周波数: {params['sampling_freq']:.1f} Hz")
8. データサイエンスでの活用
8-1. 特徴量の離散化
def discretize_feature(data, n_bins):
"""連続値特徴量の離散化"""
min_val, max_val = data.min(), data.max()
# ビン境界の生成
bin_edges = np.linspace(min_val, max_val, n_bins + 1)
# データを離散化
digitized = np.digitize(data, bin_edges) - 1
digitized = np.clip(digitized, 0, n_bins - 1)
return digitized, bin_edges
# 使用例
data = np.random.normal(50, 15, 1000)
discrete_data, edges = discretize_feature(data, 5)
print(f"離散化前の範囲: [{data.min():.1f}, {data.max():.1f}]")
print(f"ビン数: {len(np.unique(discrete_data))}")
8-2. 交差検証用のインデックス生成
def generate_cv_indices(n_samples, n_folds=5):
"""交差検証用のインデックス生成"""
indices = np.arange(n_samples)
np.random.shuffle(indices)
fold_sizes = np.full(n_folds, n_samples // n_folds)
fold_sizes[:n_samples % n_folds] += 1
folds = []
start = 0
for size in fold_sizes:
folds.append(indices[start:start + size])
start += size
return folds
# 使用例
cv_folds = generate_cv_indices(100, 5)
print(f"フォールド数: {len(cv_folds)}")
print(f"各フォールドサイズ: {[len(fold) for fold in cv_folds]}")
まとめ
NumPyのarange()とlinspace()を適切に使い分けることで、効率的な数値計算が可能になります。
選択の指針:
- 固定ステップが重要 →
arange() - 要素数が重要 →
linspace() - 浮動小数点の精密性が必要 →
linspace() - 整数インデックス →
arange()
これらの関数をマスターして、データサイエンス、科学計算、機械学習プロジェクトを効率的に進めましょう!
■プロンプトだけでオリジナルアプリを開発・公開してみた!!
■AI時代の第一歩!「AI駆動開発コース」はじめました!
テックジム東京本校で先行開始。
■テックジム東京本校
「武田塾」のプログラミング版といえば「テックジム」。
講義動画なし、教科書なし。「進捗管理とコーチング」で効率学習。
より早く、より安く、しかも対面型のプログラミングスクールです。
<短期講習>5日で5万円の「Pythonミニキャンプ」開催中。
<月1開催>放送作家による映像ディレクター養成講座
<オンライン無料>ゼロから始めるPython爆速講座


