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

Python中无公式曲线的一阶导数计算绘制及导数半最大值点提取方法

离散点曲线求导及半最大值点提取Python实现

这个需求完全可以在Python中实现,以下是可直接运行的完整方案:

前置依赖

先安装需要用到的第三方库:

pip install pandas numpy scipy matplotlib

完整实现代码

import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
from scipy.interpolate import UnivariateSpline

# 构造样本数据
data = [
    [-0.000131, 0.006983], [0.013764, 0.006666], [0.028727, 0.007242], [0.137593, 0.007117],
    [0.538855, 0.007305], [0.963937, 0.008790], [1.318019, 0.011174], [1.569953, 0.012909],
    [1.751192, 0.016706], [1.957168, 0.020321], [2.125429, 0.028622], [2.297202, 0.035952],
    [2.483939, 0.046041], [2.663194, 0.056283], [2.855580, 0.068497], [3.043233, 0.082118],
    [3.243100, 0.097764], [3.437318, 0.111928], [3.639782, 0.129328], [3.839039, 0.145694],
    [4.044403, 0.163474], [4.243966, 0.182325], [4.453453, 0.200748], [4.654542, 0.218878],
    [4.868304, 0.238715], [5.070615, 0.254610], [5.288194, 0.272639], [5.494627, 0.287299],
    [5.723200, 0.303031], [5.931618, 0.315398], [6.189813, 0.316119], [6.384031, 0.328265],
    [6.658715, 0.327107], [6.855071, 0.333307], [7.138154, 0.331096], [7.334967, 0.338243],
    [7.625989, 0.335927], [7.820513, 0.343463], [8.077639, 0.339921], [8.264375, 0.349140],
    [8.473862, 0.344021], [8.652201, 0.349255], [8.816034, 0.346376], [8.944750, 0.345141],
    [9.079573, 0.344968], [9.130418, 0.344184], [9.255163, 0.342439], [9.195768, 0.345535],
    [9.247223, 0.344030], [9.192867, 0.345617], [9.281273, 0.337575]
]
df = pd.DataFrame(data, columns=['X', 'y'])
# 按X值排序,避免离散点顺序混乱导致求导错误
df = df.sort_values('X').reset_index(drop=True)
x = df['X'].values
y = df['y'].values

# 1. 样条插值拟合平滑曲线,s参数控制平滑度,可根据实际效果调整
spl = UnivariateSpline(x, y, s=0.001)
# 生成更密集的采样点用于求导和绘图
x_dense = np.linspace(x.min(), x.max(), 1000)
y_smooth = spl(x_dense)

# 2. 计算一阶导数
dy_dx = spl.derivative(n=1)(x_dense)

# 3. 找到导数最大值的一半对应的坐标
max_deriv = dy_dx.max()
half_max_deriv = max_deriv / 2
# 找到导数从低于半值到高于半值的交点位置
cross_idx = np.where(np.diff(np.sign(dy_dx - half_max_deriv)))[0][0]
# 线性插值计算精确的X坐标
x_half = np.interp(half_max_deriv, dy_dx[cross_idx:cross_idx+2], x_dense[cross_idx:cross_idx+2])
y_half = spl(x_half)

# 4. 可视化
plt.rcParams['font.sans-serif'] = ['SimHei']
plt.rcParams['axes.unicode_minus'] = False

fig, (ax1, ax2) = plt.subplots(2, 1, figsize=(10, 8))
# 原始曲线
ax1.plot(x, y, 'o', label='原始离散点', markersize=3, alpha=0.6)
ax1.plot(x_dense, y_smooth, label='拟合平滑曲线')
ax1.scatter(x_half, y_half, c='red', s=50, zorder=5, label=f'导数半值点\nX={x_half:.2f}, y={y_half:.3f}')
ax1.set_xlabel('X')
ax1.set_ylabel('y')
ax1.set_title('原始曲线及导数半值点')
ax1.legend()
ax1.grid(alpha=0.3)

# 一阶导数曲线
ax2.plot(x_dense, dy_dx, label='一阶导数')
ax2.axhline(max_deriv, c='green', linestyle='--', label=f'导数最大值={max_deriv:.3f}')
ax2.axhline(half_max_deriv, c='orange', linestyle='--', label=f'导数半最大值={half_max_deriv:.3f}')
ax2.scatter(x_half, half_max_deriv, c='red', s=50, zorder=5)
ax2.set_xlabel('X')
ax2.set_ylabel('dy/dx')
ax2.set_title('一阶导数曲线')
ax2.legend()
ax2.grid(alpha=0.3)

plt.tight_layout()
plt.show()

# 输出结果
print(f"一阶导数最大值为: {max_deriv:.4f}")
print(f"导数达到最大值一半时对应的坐标点: X={x_half:.4f}, y={y_half:.4f}")

效果说明

原始曲线示意图如下:
曲线示意图
运行代码后会输出两个可视化图表,同时打印目标坐标点的数值,可调整样条插值的s参数控制平滑度,匹配实际的曲线拟合需求。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.05 21:24:03