【问题标题】:Difficulties to use scipy.interpolate BSpline: "TypeError: 'list' object cannot be interpreted as an integer"使用 scipy.interpolate BSpline 的困难:“TypeError:'list' 对象不能解释为整数”
【发布时间】:2020-05-10 01:47:51
【问题描述】:

来自here

  • splrep 可以根据路径和平滑因子计算 B-Spline 节点、系数和度数
  • splev 使用生成的 B 样条启用插值
  • BSpline 可以直接从节点、系数和度数构建样条

那么,我应该被允许表演:

import numpy as np
from scipy.interpolate import splev, splprep, BSpline
path =  [(2077.0, 712.0, 1136.6176470588234), (2077.0004154771536, 974.630482962754, 1313.735294117647), (2077.1630960823995, 1302.460574562254, 1490.8529411764707), (2078.1944091179635, 1674.693193015173, 1667.9705882352941), (2080.5096120056783, 2086.976611915444, 1845.0882352941176), (2085.1051468332066, 2711.054258877495, 2022.2058823529412), (1477.0846185328733, 2803.6223679691457, 2199.323529411765), (948.4693105162195, 2802.0390667447105, 2376.4411764705883), (383.8615403256207, 2804.843424134807, 2553.5588235294117), (-41.6669725172834, 2497.067373170676, 2730.676470588235), (-37.94311919744064, 1970.5155845437525, 2907.794117647059), (-35.97395938535092, 1576.713103381243, 3084.9117647058824), (-35.125016151504795, 1214.2319876178394, 3262.029411764706), (-35.000550767864524, 893.3910350913443, 3439.1470588235297), (-35.0, 631.2108462417168, 3616.264705882353), (-35.0, 365.60545190581837, 3793.3823529411766), (-35.0, 100.00005756991993, 3970.5)]
p = [[x for x,y,z in path], [y for x,y,z in path], [z for x,y,z in path]]
tck, u = splprep(p, k=3)
t, c0, k = tck
sp = BSpline(t, k, c0)

目标是能够调整 B 样条。但是BSpline 对我的论点不满意:

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/home/lalebarde/anaconda3/lib/python3.7/site-packages/scipy/interpolate/_bsplines.py", line 184, in __init__
    self.k = operator.index(k)
TypeError: 'list' object cannot be interpreted as an integer

如果我检查变量的形状和类型:

type(t)
<class 'numpy.ndarray'>
type(c0)
<class 'list'>
type(k)
<class 'int'>
t.shape
(21,)
np.array(c0).shape
(3, 17)

我对 BSpline 的使用失败,来自 documentation

class scipy.interpolate.BSpline(t, c, k, extrapolate=True, axis=0)

t: ndarray, shape (n+k+1,) --> 结

c: ndarray, shape (>=n, …) --> spline coefficients - k 次样条曲线至少需要 k+1 个系数,因此 n >= k+1。 j > n 的附加系数 c[j] 将被忽略。

k: int --> B样条顺序

除了系数c 应该是与我的路径p 长度相同的一维向量。

例如,sp = BSpline(t, c0[0], k) 执行时没有错误,与 c0[1]c0[2] 一样,但当然,我希望使用由 splprep 计算的所有系数。

来自here,看来 scipy interpolate 手册令人困惑:

tck[1]:重定位控制点的x和y坐标

手册说:

(t,c,k) 包含节点向量、B 样条系数和样条度数的元组

最终,我误用了 BSpline,错误解释了它的 样条系数参数

那么,如何从splprepBSpline 或其他函数返回的结点和系数构建 BSpline?

【问题讨论】:

    标签: python scipy interpolation bspline


    【解决方案1】:

    BSpline(t, k, c0) 应该是BSpline(t, c0, k)

    编辑。其实还有一个问题:splprep返回的数组列表和BSpline不一致。

    注意splrep和spl的区别prep:

    基本上splrep/splev是一致的,splrep/BSpline是一致的,但是splprep/BSpline不是。这是一个已知的疣,不能以向后兼容的方式修复。

    如果你想一起使用它们,你需要转置c 数组。 基于您的 OP 示例:

    In [1]: import numpy as np
       ...: from scipy.interpolate import splev, splprep, BSpline
       ...: path =  [(2077.0, 712.0, 1136.6176470588234), (2077.0004154771536, 974.6
       ...: 30482962754, 1313.735294117647), (2077.1630960823995, 1302.460574562254,
       ...:  1490.8529411764707), (2078.1944091179635, 1674.693193015173, 1667.97058
       ...: 82352941), (2080.5096120056783, 2086.976611915444, 1845.0882352941176), 
       ...: (2085.1051468332066, 2711.054258877495, 2022.2058823529412), (1477.08461
       ...: 85328733, 2803.6223679691457, 2199.323529411765), (948.4693105162195, 28
       ...: 02.0390667447105, 2376.4411764705883), (383.8615403256207, 2804.84342413
       ...: 4807, 2553.5588235294117), (-41.6669725172834, 2497.067373170676, 2730.6
       ...: 76470588235), (-37.94311919744064, 1970.5155845437525, 2907.794117647059
       ...: ), (-35.97395938535092, 1576.713103381243, 3084.9117647058824), (-35.125
       ...: 016151504795, 1214.2319876178394, 3262.029411764706), (-35.0005507678645
       ...: 24, 893.3910350913443, 3439.1470588235297), (-35.0, 631.2108462417168, 3
       ...: 616.264705882353), (-35.0, 365.60545190581837, 3793.3823529411766), (-35
       ...: .0, 100.00005756991993, 3970.5)]
       ...: p = [[x for x,y,z in path], [y for x,y,z in path], [z for x,y,z in path]
       ...: ]
       ...: tck, u = splprep(p, k=3, s=0)      # ADDED s=0 for clarity
       ...: 
    
    In [2]: t, c, k = tck
    
    In [3]: c1 = np.asarray(c)
    
    In [4]: spl = BSpline(t, c1.T, k)         # Note the transpose
    
    In [5]: spl(u) - path                     # these should match, and they do
    Out[5]: 
    array([[ -4.54747351e-13,  -1.13686838e-13,  -4.54747351e-13],
           [  0.00000000e+00,  -1.13686838e-13,   0.00000000e+00],
           [ -4.54747351e-13,   0.00000000e+00,   0.00000000e+00],
           [  0.00000000e+00,  -2.27373675e-13,  -2.27373675e-13],
           [ -4.54747351e-13,   0.00000000e+00,   4.54747351e-13],
           [ -4.54747351e-13,   0.00000000e+00,  -6.82121026e-13],
           [  2.27373675e-13,   0.00000000e+00,   0.00000000e+00],
           [ -1.13686838e-13,  -4.54747351e-13,  -4.54747351e-13],
           [  0.00000000e+00,   0.00000000e+00,   0.00000000e+00],
           [  4.26325641e-14,  -9.09494702e-13,   0.00000000e+00],
           [  1.42108547e-14,  -4.54747351e-13,   0.00000000e+00],
           [  0.00000000e+00,   0.00000000e+00,   0.00000000e+00],
           [  7.10542736e-15,   0.00000000e+00,  -4.54747351e-13],
           [  0.00000000e+00,  -3.41060513e-13,   0.00000000e+00],
           [ -7.10542736e-15,  -1.13686838e-13,   0.00000000e+00],
           [  0.00000000e+00,   0.00000000e+00,   0.00000000e+00],
           [  0.00000000e+00,   0.00000000e+00,   0.00000000e+00]])
    

    此答案基于https://github.com/scipy/scipy/issues/10389。 那里的一般建议适用:如果你想要插值,更喜欢make_interp_spline 而不是splrepsplprep。如果你想要平滑,目前只有 FITPACK,要么是 splrep(与 BSpline 兼容),要么是 splprep(需要手动转置)。

    【讨论】:

    • 然后我得到:&gt;&gt;&gt; sp = BSpline(t, c0, k) Traceback (most recent call last): File "&lt;stdin&gt;", line 1, in &lt;module&gt; File "/home/lalebarde/anaconda3/lib/python3.7/site-packages/scipy/interpolate/_bsplines.py", line 223, in __init__ raise ValueError("Knots, coefficients and degree are inconsistent.") ValueError: Knots, coefficients and degree are inconsistent.
    • 啊,好的,你正在使用 splprep。请参阅编辑后的答案。
    猜你喜欢
    • 2017-08-01
    • 2021-07-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-12-05
    • 2015-03-18
    • 2016-01-26
    • 2021-02-10
    相关资源
    最近更新 更多