如何对x与y的加权平均值(由x加权)进行平滑和绘制?

Pyt*_*ous 6 python matplotlib weighted-average pandas pandas-groupby

我有一个带有一列权重和一个值的数据框。我需要:

  • discretise权重,并且对于权重的每个间隔,绘制的值的加权平均值,然后
  • 将相同的逻辑扩展到另一个变量:离散z,并针对每个间隔绘制值的加权平均值,并按权重加权

有找到一种简单的方法吗?我找到了一种方法,但是似乎有点麻烦:

  • 我用pandas.cut()离散化数据框
  • 进行分组并计算加权平均值
  • 绘制每个仓位的平均值与加权平均值的关系图
  • 我也尝试用样条曲线使曲线平滑,但效果不大

基本上,我正在寻找一种更好的方法来产生更平滑的曲线。

我的输出看起来像这样: 在此处输入图片说明

我的代码(带有一些随机数据)是:

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
from scipy.interpolate import make_interp_spline, BSpline

n=int(1e3)
df=pd.DataFrame()
np.random.seed(10)
df['w']=np.arange(0,n)
df['v']=np.random.randn(n)
df['ranges']=pd.cut(df.w, bins=50)
df['one']=1.
def func(x, df):
    # func() gets called within a lambda function; x is the row, df is the entire table
    b1= x['one'].sum()
    b2 = x['w'].mean()
    b3 = x['v'].mean()       
    b4=( x['w'] * x['v']).sum() / x['w'].sum() if x['w'].sum() >0 else np.nan

    cols=['# items','avg w','avg v','weighted avg v']
    return pd.Series( [b1, b2, b3, b4], index=cols )

summary = df.groupby('ranges').apply(lambda x: func(x,df))

sns.set(style='darkgrid')

fig,ax=plt.subplots(2)
sns.lineplot(summary['avg w'], summary['weighted avg v'], ax=ax[0])
ax[0].set_title('line plot')

xnew = np.linspace(summary['avg w'].min(), summary['avg w'].max(),100)
spl = make_interp_spline(summary['avg w'], summary['weighted avg v'], k=5) #BSpline object
power_smooth = spl(xnew)
sns.lineplot(xnew, power_smooth, ax=ax[1])
ax[1].set_title('not-so-interpolated plot')
Run Code Online (Sandbox Code Playgroud)

小智 0

如果我理解正确的话,您正在尝试重新创建滚动平均值。

这已经是 Pandas 数据帧的功能,使用以下rolling函数:

dataframe.rolling(n).mean()

其中n是“窗口”或“箱”中用于平均值的相邻点的数量,因此您可以调整它以获得不同程度的平滑度。

您可以在这里找到示例: