我试图绘制一个分段拟合的数据,但我需要用任意数量的线段来绘制。有时有三段,有时有两段。我在btable中存储了fit-in-actable的系数和线段的边界。在
以下是我的边界值示例:
btable = [[0.00499999989, 0.0244274978], [0.0244275965, 0.0599999987]]
以下是我的系数的示例值:
^{pr2}$我的代码如下:
rfig = plt.figure()
<>various other plot specifications<>
x = np.arange(0.005, 0.06, 0.0001)
y = np.piecewise(x, [(x >= btable[i][0]) & (x <= btable[i][1]) for i in range(len(btable))], [lambda x=x: np.log10(actable[j][0] + actable[j][2] * x + actable[j][2] * x**2) for j in list(range(len(actable)))])
plt.plot(x, y)
问题是lambda将自己设置为列表的最后一个实例,因此它使用所有分段的最后一个分段的系数。我不知道如何在不使用lambda的情况下实现分段函数。在
目前,我这样做是在作弊:
if len(btable) == 2:
y = np.piecewise(x, [(x >= btable[i][0]) & (x <= btable[i][1]) for i in range(len(btable))], [lambda x: np.log10(actable[0][0] + actable[0][1] * x + actable[0][2] * x**2), lambda x: np.log10(actable[1][0] + actable[1][1] * x + actable[1][2] * x**2)])
else if len(btable) == 3:
y = np.piecewise(x, [(x >= btable[i][0]) & (x <= btable[i][1]) for i in range(len(btable))], [lambda x: np.log10(actable[0][0] + actable[0][1] * x + actable[0][2] * x**2), lambda x: np.log10(actable[1][0] + actable[1][1] * x + actable[1][2] * x**2), lambda x: np.log10(actable[2][0] + actable[2][1] * x + actable[2][2] * x**2)])
else
print('Oh no! You have fewer than 2 or more than 3 segments!')
但这让我内心感到恶心。我知道一定有更好的解决办法。有人能帮忙吗?在
这个问题很常见,Python的官方文档中有一篇文章Why do lambdas defined in a loop with different values all return the same result?,给出了一个建议的解决方案:创建一个由循环变量初始化的局部变量,以便在函数中捕捉后者不断变化的值。在
也就是说,在
y
的定义中,替换它就足够了通过
^{pr2}$顺便说一下,我们可以使用单侧不等式来指定一块一块的:计算为True的最后一个将触发相应的函数。(这有点违反直觉;使用第一个真条件会更自然,就像SymPy那样)。如果断点按递增顺序排列,则应使用“x>;=”不等式:
这里,每个系数将用于以相应断点开始的间隔;例如,系数c=0用于范围
0<=x<1
,系数c=2在范围1<=x<2
中,等等。在相关问题 更多 >
编程相关推荐