【发布时间】:2019-08-23 03:50:21
【问题描述】:
我有一个数据框,其中有一列权重和一个值。我需要:
- 离散权重,并为每个权重区间绘制 加权平均值,然后
- 将相同的逻辑扩展到另一个 变量:离散 z,并为每个区间绘制加权的 值的平均值,按权重加权
有没有简单的方法可以实现?我找到了方法,但是好像有点麻烦:
- 我用 pandas.cut() 离散化数据帧
- 进行分组并计算加权平均值
- 绘制每个 bin 的平均值与加权平均值的关系
- 我也尝试过用样条曲线平滑曲线,但效果不大
基本上我正在寻找一种更好的方法来产生更平滑的曲线。
我的代码和一些随机数据是:
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')
【问题讨论】:
-
你的平均权重是多少?
-
想象一个具有 3 列的数据框:w、x、y。我离散 x;对于如此离散的 x 的每个桶,我想计算 y 的加权平均值,由 w 加权。
-
请注意,您的评论与问题不同(您要离散权重还是 x?)此外,关于平滑的句子也不清楚。计算加权平均值不一定会平滑任何东西,这取决于权重,对吧?那么目的是平滑的吗?还是计算加权平均值?
-
你说得对,我不清楚。实际上,我有时会通过权重进行离散化,有时会通过另一个变量进行离散化。加权平均值与平滑无关 - 平滑是一个单独的点。
-
@Pythonistaanonymous 你考虑过使用内核吗?对我来说,这似乎是正确的方法
标签: python pandas matplotlib pandas-groupby weighted-average