Python 在Pandas中获取多个列的加权平均值和标准偏差
我试图在我的Python 在Pandas中获取多个列的加权平均值和标准偏差,python,pandas,grouping,aggregate,weighted-average,Python,Pandas,Grouping,Aggregate,Weighted Average,我试图在我的pandasdataframe的加权平均值的基础上进行加权标准差。我有一个pandas数据帧,如: import numpy as np import pandas as pd df = pd.DataFrame({"Date": pd.date_range(start='2018-01-01', end='2018-01-03 18:00:00', freq='6H'), "Weight": np.random.uniform(3, 5, 12),
pandas
dataframe的加权平均值的基础上进行加权标准差。我有一个pandas
数据帧,如:
import numpy as np
import pandas as pd
df = pd.DataFrame({"Date": pd.date_range(start='2018-01-01', end='2018-01-03 18:00:00', freq='6H'),
"Weight": np.random.uniform(3, 5, 12),
"V1": np.random.uniform(10, 15, 12),
"V2": np.random.uniform(10, 15, 12),
"V3": np.random.uniform(10, 15, 12)})
目前,为了获得加权平均值,受启发,我正在做以下工作:
def weighted_average_std(grp):
return grp._get_numeric_data().multiply(grp['Weight'], axis=0).sum()/grp['Weight'].sum()
df.index = df["Date"]
df_agg = df.groupby(pd.Grouper(freq='1D')).apply(weighted_average_std).reset_index()
df_agg
Date V1 V2 V3 Weight
0 2018-01-01 11.421749 13.090178 11.639424 3.630196
1 2018-01-02 12.142917 11.605284 12.187473 4.056303
2 2018-01-03 12.034015 13.159132 11.658969 4.318753
我从中得到以下信息:
def weighted_average_std(grp):
return grp._get_numeric_data().multiply(grp['Weight'], axis=0).sum()/grp['Weight'].sum()
df.index = df["Date"]
df_agg = df.groupby(pd.Grouper(freq='1D')).apply(weighted_average_std).reset_index()
df_agg
Date V1 V2 V3 Weight
0 2018-01-01 11.421749 13.090178 11.639424 3.630196
1 2018-01-02 12.142917 11.605284 12.187473 4.056303
2 2018-01-03 12.034015 13.159132 11.658969 4.318753
我想修改加权平均值
,这样除了加权平均值
之外,它还会返回每列的标准偏差。其思想是以矢量化的方式使用每组的加权平均值。加权标准偏差
的新列名可能类似于V1\u WSD
、V2\u WSD
和V3\u WSD
PS1:通过加权标准差理论
PS2:df_agg
中的列Weight
没有意义 您可以使用
计算加权平均数和标准差。要在Pandasgroupby/apply
操作中使用此选项,请使weighted\u average\u std
返回一个数据帧:
import numpy as np
import pandas as pd
def weighted_average_std(grp):
"""
Based on http://stackoverflow.com/a/2415343/190597 (EOL)
"""
tmp = grp.select_dtypes(include=[np.number])
weights = tmp['Weight']
values = tmp.drop('Weight', axis=1)
average = np.ma.average(values, weights=weights, axis=0)
variance = np.dot(weights, (values - average) ** 2) / weights.sum()
std = np.sqrt(variance)
return pd.DataFrame({'mean':average, 'std':std}, index=values.columns)
np.random.seed(0)
df = pd.DataFrame({
"Date": pd.date_range(start='2018-01-01', end='2018-01-03 18:00:00', freq='6H'),
"Weight": np.random.uniform(3, 5, 12),
"V1": np.random.uniform(10, 15, 12),
"V2": np.random.uniform(10, 15, 12),
"V3": np.random.uniform(10, 15, 12)})
df.index = df["Date"]
df_agg = df.groupby(pd.Grouper(freq='1D')).apply(weighted_average_std).unstack(-1)
print(df_agg)
屈服
mean std
V1 V2 V3 V1 V2 V3
Date
2018-01-01 12.105253 12.314079 13.566136 1.803014 1.725761 0.679279
2018-01-02 13.223172 12.534893 11.860456 1.709583 0.950338 1.153895
2018-01-03 13.782625 12.013557 12.105231 0.969099 1.189149 1.249064
这很有效。您能解释一下
unstack(-1)
的作用吗?最好的理解方法是使用示例(例如链接页面上显示的示例,或者此处显示的示例)。考虑它的一种方法是集中于它如何影响行和列索引--unstack
将行索引级别移动到新的列索引级别。根据需要对数据进行重塑。-1
告诉unstack
移动最后一行索引级别--V1
,V2
,V3
值,而不是有意义的日期。我使用下面的一行使列名平铺。请让我们知道是否有更优雅的方式来做这件事。它将导致V1_std
和V1_mean
名称的种类,df_agg.columns=[col[1]+“_”+col[0]如果(col[0]!=”和col[1]!=”)否则df_agg.columns.values中col的col[1]+col[0]会起作用,或者您可以使用类似于df_agg.columns=df agg.swaplevel(axis=1).columns.map('.join)
。请注意,保留可以是有利的,特别是如果您希望,例如,仅选择平均值,或仅选择STD,或仅选择与V1
相关的数据。更改为np.ma.average
。链接的文档页面指向答案(搜索ZeroDivisionError
)。通过此更改,df_agg
将具有带有NaNs
的行。如果要删除这些行,请使用df\u agg=df\u agg.dropna()
。