如何找到曲线(如 np.array)与 y==0 的确切交点?

Posted

技术标签:

【中文标题】如何找到曲线(如 np.array)与 y==0 的确切交点?【英文标题】:How to find the exact intersection of a curve (as np.array) with y==0? 【发布时间】:2018-04-05 04:23:30 【问题描述】:

如何从 Python 中的绘图中获得 y 轴上的精确值?我有两个数组vertical_datagradient(temperature_data),我将它们绘制为:

plt.plot(gradient(temperature_data),vertical_data)
plt.show()

此处显示的情节:

我需要零值,但它不完全为零,它是一个浮点数。

【问题讨论】:

我猜问题描述有点误导,如果存在的话。你想要的是找到一个 numpy 数组的零。这与 matplotlib 无关。 (也有不止一个零)。这通常是一项不平凡的任务。但根据所需的精度,可以简化。 嗯,我想我应该在那个绘制的图中看到它 【参考方案1】:

对于如何找到 numpy 数组的根或零的问题,我没有找到一个好的答案,所以这里有一个解决方案,使用简单的线性插值。

import numpy as np
N = 750
x = .4+np.sort(np.random.rand(N))*3.5
y = (x-4)*np.cos(x*9.)*np.cos(x*6+0.05)+0.1


def find_roots(x,y):
    s = np.abs(np.diff(np.sign(y))).astype(bool)
    return x[:-1][s] + np.diff(x)[s]/(np.abs(y[1:][s]/y[:-1][s])+1)

z = find_roots(x,y)

import matplotlib.pyplot as plt

plt.plot(x,y)
plt.plot(z, np.zeros(len(z)), marker="o", ls="", ms=4)

plt.show()

当然你可以颠倒xy的角色得到

plt.plot(y,x)
plt.plot(np.zeros(len(z)),z, marker="o", ls="", ms=4)


因为人们询问如何在非零值y0 处获得截距,请注意,人们可能会简单地找到y-y0 的零。
y0 = 1.4
z = find_roots(x,y-y0)
# ...
plt.plot(z, np.zeros(len(z))+y0)


人们还问如何获得两条曲线之间的交点。在那种情况下,它又是关于找到两者之间差异的根源,例如

x = .4 + np.sort(np.random.rand(N)) * 3.5
y1 = (x - 4) * np.cos(x * 9.) * np.cos(x * 6 + 0.05) + 0.1
y2 = (x - 2) * np.cos(x * 8.) * np.cos(x * 5 + 0.03) + 0.3

z = find_roots(x,y2-y1)

plt.plot(x,y1)
plt.plot(x,y2, color="C2")
plt.plot(z, np.interp(z, x, y1), marker="o", ls="", ms=4, color="C1")

【讨论】:

嘿,只是想说将函数符号更改符号的地方变成这样的索引是一个好主意。谢谢! @JohanC 对于规则间隔的数据,可以将np.diff(x)[s] 替换为(x[1]-x[0])。如果这就是你的意思,那只会带来非常小的性能提升。 为什么return x[:-1][s] + np.diff(x)[s]/(np.abs(y[1:][s]/y[:-1][s])+1) 中的最后一个“+1”?

以上是关于如何找到曲线(如 np.array)与 y==0 的确切交点?的主要内容,如果未能解决你的问题,请参考以下文章

第三章 线性回归

在某些条件下,找到两个数组之间(逐项)比率的最大值或最小值

关于Numpy中+=与-=操作符不支持数组广播的特性

如何用MATLAB绘制双曲线?

python曲线拟合

将高阶矩阵与 numpy 相乘