You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

R语言bs()样条函数生成B样条基矩阵的Python等价实现方法查询

R中splines::bs生成B样条基矩阵的Python等价实现

你之前直接调用scipy.interpolate.BSpline类无法生成基矩阵,是因为该类默认用于拟合完成后的样条预测,我们可以通过以下两种方案实现和R一致的基矩阵生成逻辑,仅需传入输入数组、内部节点、阶数三个参数即可。


方案1:基于scipy原生实现(无需额外安装第三方库)

核心逻辑是手动构造R的bs函数默认的钳位节点序列,再调用BSpline的静态方法计算每个基函数的取值,最终拼接为基矩阵:

import numpy as np
from scipy.interpolate import BSpline

def get_bspline_basis(x, internal_knots, degree):
    # 构造完整节点序列:首尾各加degree个和x边界值一致的节点
    x_min, x_max = x.min(), x.max()
    full_knots = np.concatenate([
        [x_min]*degree,
        internal_knots,
        [x_max]*degree
    ])
    # 基函数总数 = 内部节点数 + 阶数
    n_basis = len(internal_knots) + degree
    basis_mat = np.zeros((len(x), n_basis))
    # 逐个生成每个基函数的取值
    for i in range(n_basis):
        knots_i = full_knots[i:i+degree+2]
        basis = BSpline.basis_element(knots_i, extrapolate=False)
        basis_mat[:, i] = basis(x)
    # 边界外的空值补0,和R的bs行为完全对齐
    basis_mat = np.nan_to_num(basis_mat, nan=0.0)
    return basis_mat

# 样例测试
women_height = np.array([58,59,60,61,62,63,64,65,66,67,68,69,70,71,72])
knots = np.array([59.4, 62.2, 65. , 67.8, 70.6])
degree = 3

bs_mat = get_bspline_basis(women_height, knots, degree)
print(bs_mat)

方案2:基于patsy库实现(和Rsplines::bs行为100%兼容)

patsy是Python中专门用于统计模型公式解析的库,内置的bs函数参数、输出逻辑和R完全一致,使用更简便:

  1. 先安装依赖:pip install patsy
  2. 调用代码:
import numpy as np
from patsy import bs

women_height = np.array([58,59,60,61,62,63,64,65,66,67,68,69,70,71,72])
knots = np.array([59.4, 62.2, 65. , 67.8, 70.6])
degree = 3

# 直接生成基矩阵,参数规则和R完全一致
bs_mat = bs(women_height, knots=knots, degree=degree, include_intercept=False)
print(bs_mat)

如果需要生成包含截距项的基矩阵,仅需将include_intercept参数设为True即可。


内容的提问来源于stack exchange,提问作者ignoring_gravity

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.05 03:09:01