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

不同采样点下采样数据均值的绘制方法咨询

非重合采样点的多组数据均值绘制方案

问题背景

需要绘制多组采样数据的均值曲线,但各组对应的采样点x并不重合,且x取值范围限定在0到1之间。给定的示例代码如下:

import matplotlib.pyplot as plt

x1 = [0.1, 0.2, 0.4, 0.6, 0.75, 0.9]
x2 = [0, 0.14, 0.53, 0.6, 0.81, 0.9, 0.98]

y1 = [1, 4, 6, 5, 5, 3]
y2 = [3, 4, 7, 9, 7, 4, 2]

plt.plot(x1, y1, marker='o')
plt.plot(x2, y2, marker='x')
plt.grid()
plt.xlabel('x')
plt.ylabel('y')
plt.show()

以下是几种符合Python风格的优雅实现方式,包含插值方案和更优替代方案:


一、插值统一x轴(标准方案)

如果需要严格对齐x轴后计算均值,用numpy.interp或scipy.interp1d实现是最直接且Pythonic的方式。可以封装成通用函数处理多组数据:

实现代码

import numpy as np
import matplotlib.pyplot as plt

# 定义通用插值函数
def interpolate_and_average(x_list, y_list, num_points=100):
    # 生成统一的x轴(0到1之间均匀采样)
    x_uniform = np.linspace(0, 1, num_points)
    # 对每组数据插值
    y_interpolated = [np.interp(x_uniform, x, y) for x, y in zip(x_list, y_list)]
    # 计算均值
    y_mean = np.mean(y_interpolated, axis=0)
    return x_uniform, y_mean

# 准备数据
x_data = [x1, x2]
y_data = [y1, y2]

# 计算插值后的均值曲线
x_uniform, y_mean = interpolate_and_average(x_data, y_data)

# 绘图
plt.plot(x1, y1, marker='o', alpha=0.5, label='Dataset 1')
plt.plot(x2, y2, marker='x', alpha=0.5, label='Dataset 2')
plt.plot(x_uniform, y_mean, color='red', linewidth=2, label='Mean Curve')
plt.grid()
plt.xlabel('x')
plt.ylabel('y')
plt.legend()
plt.show()

优势

  • 逻辑清晰,代码简洁,符合Python的函数式编程风格
  • 可以灵活控制采样点数,平衡精度和效率
  • 支持扩展到任意多组数据

二、无需统一x轴的替代方案

如果不需要强制对齐x点,而是想要更平滑的均值趋势,可以用核密度估计(KDE)或局部加权回归(LOWESS),这类方法更适合数据分布有规律的场景:

1. 核密度估计(KDE)平滑均值

利用KDE对所有(x,y)点进行加权,生成平滑的均值曲线:

import numpy as np
import matplotlib.pyplot as plt
from scipy.stats import gaussian_kde

# 合并所有数据点
all_x = np.concatenate([x1, x2])
all_y = np.concatenate([y1, y2])

# 生成KDE模型,计算每个x点的加权均值
x_uniform = np.linspace(0, 1, 100)
kde = gaussian_kde(np.vstack([all_x, all_y]))

# 计算每个x对应的y均值(通过KDE加权)
y_mean = []
for x in x_uniform:
    # 固定x,采样y的条件分布
    y_samples = kde.resample(size=1000, seed=42)[1]
    y_mean.append(np.mean(y_samples))

# 绘图
plt.plot(x1, y1, marker='o', alpha=0.5, label='Dataset 1')
plt.plot(x2, y2, marker='x', alpha=0.5, label='Dataset 2')
plt.plot(x_uniform, y_mean, color='green', linewidth=2, label='KDE Mean Curve')
plt.grid()
plt.xlabel('x')
plt.ylabel('y')
plt.legend()
plt.show()

2. 局部加权回归(LOWESS)

用LOWESS拟合所有数据点,得到平滑的趋势线,本质是局部区域内的加权均值:

import numpy as np
import matplotlib.pyplot as plt
from statsmodels.nonparametric.smoothers_lowess import lowess

# 合并所有数据点
all_x = np.concatenate([x1, x2])
all_y = np.concatenate([y1, y2])

# 用LOWESS拟合
lowess_result = lowess(all_y, all_x, frac=0.3)  # frac控制平滑程度
x_smooth = lowess_result[:, 0]
y_smooth = lowess_result[:, 1]

# 绘图
plt.plot(x1, y1, marker='o', alpha=0.5, label='Dataset 1')
plt.plot(x2, y2, marker='x', alpha=0.5, label='Dataset 2')
plt.plot(x_smooth, y_smooth, color='blue', linewidth=2, label='LOWESS Mean Curve')
plt.grid()
plt.xlabel('x')
plt.ylabel('y')
plt.legend()
plt.show()

优势

  • 不需要强制插值,保留原始数据的分布特征
  • 生成的曲线更平滑,适合展示整体趋势
  • 对数据中的噪声有一定的鲁棒性

方案选择建议

  • 如果需要精确对齐x点并计算均值,优先选择插值方案
  • 如果更关注整体趋势的平滑展示,且数据分布有规律,建议用KDE或LOWESS
  • 多组数据量较大时,插值方案的效率更高;数据量较小时,KDE/LOWESS的效果更自然

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.21 17:53:10