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

如何使用curve_fit为DataFrame数据做幂律拟合并绘制正确曲线

问题原因

你的代码拟合失败来自三个核心错误:

  • 单位理解错误:表中rcs列是dBsm(分贝平方米)的对数域数值,不是线性域RCS。雷达方程中线性域RCS和距离四次方成正比,但dB域下该关系为对数线性形式,直接用线性值套a*range^4公式完全不匹配。
  • 拟合参数错误:幂律拟合对初始参数敏感度极高,curve_fit默认初始参数为1,对你这种数值量级跨度大的场景会直接收敛到局部最优,得到完全错误的拟合结果。
  • 绘图逻辑错误:一方面你拟合的是rcs = f(range),即range为自变量、rcs为因变量,但绘图时把rcs放在x轴、range放在y轴,坐标轴对应关系完全颠倒;另一方面直接用原始离散的range点绘图,没有生成连续密集的插值序列,画出来的自然是折线段而非平滑曲线。

正确实现方案

你可以选择两种方式完成拟合,两种结果完全一致:

方案1:线性域幂律拟合

先把dB单位的rcs转换为线性值,设置合理初始参数完成拟合,再生成连续序列绘制平滑曲线:

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from scipy.optimize import curve_fit

# 加载你的数据
df = pd.DataFrame({
    'rcs': [-40,-35,-30,-25,-20,-15,-10,-5,0,5],
    'range': [12.9,14.9,22.9,35.44,43.48,62.4,92.4,132.99,182.6,252.99]
})

# 定义四次幂律函数(线性域)
def power_law(x, a):
    return a * np.power(x, 4)

x = df['range'].values
# 关键转换:dB转线性RCS
y_linear = 10 ** (df['rcs'].values / 10)

# 用第一个点估算初始参数a,避免拟合收敛到错误值
a_init = y_linear[0] / (x[0] ** 4)
pop, _ = curve_fit(power_law, x, y_linear, p0=[a_init])
a_fit = pop[0]

# 生成200个连续点用于绘制平滑曲线
x_smooth = np.linspace(x.min(), x.max(), 200)
y_smooth = power_law(x_smooth, a_fit)

# 绘图
plt.figure(figsize=(8,5))
plt.scatter(x, df['rcs'].values, label='原始散点', color='tab:blue')
# 拟合结果转回dB单位和原始散点对齐
plt.plot(x_smooth, 10*np.log10(y_smooth), color='red', 
         label=f'拟合曲线: σ(线性) = {a_fit:.2e} * R^4')
plt.xlabel('range')
plt.ylabel('rcs (dBsm)')
plt.legend()
plt.grid(alpha=0.3)
plt.show()

方案2:dB域线性拟合(雷达数据处理常规方案)

dB域下四次方关系转换为线性形式:rcs_dB = 40*log10(range) + b,不需要非线性最小二乘,直接计算截距即可,拟合结果更稳定:

x = df['range'].values
y_dB = df['rcs'].values
x_log = np.log10(x)

# 斜率固定为40,直接计算平均截距
b_fit = (y_dB - 40 * x_log).mean()

# 生成平滑曲线点
x_smooth = np.linspace(x.min(), x.max(), 200)
y_smooth_dB = 40 * np.log10(x_smooth) + b_fit

# 绘图
plt.figure(figsize=(8,5))
plt.scatter(x, y_dB, label='原始散点', color='tab:blue')
plt.plot(x_smooth, y_smooth_dB, color='red',
         label=f'拟合曲线: rcs(dB) = 40*log10(R) + {b_fit:.2f}')
plt.xlabel('range')
plt.ylabel('rcs (dBsm)')
plt.legend()
plt.grid(alpha=0.3)
plt.show()

原代码问题对应说明
  • 多项式拟合曲线不平滑:直接传入10个离散的原始range点绘图,连接后为折线,必须用np.linspace生成密集连续的x序列才能得到平滑曲线。
  • 幂律拟合线不穿过散点:未做dB到线性值的单位转换,且未设置合理初始参数,拟合完全不收敛到正确结果。
  • 曲线起点不匹配:坐标轴对应关系颠倒,拟合和绘图的自变量、因变量没有对齐。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.26 18:48:25