使用describe()函数处理加权数据——均值、标准差、中位数、分位数。

14

作为一个SAS分析平台的用户,我刚接触Python和Pandas,如果这个问题已经有人问过/回答过,请提前谅解。(我已经搜索了文档和本网站,但还没有找到答案。)

我有一个名为resp的数据框,其中包含受访者调查数据。我想对其中一个字段(称为anninc,代表年收入)执行一些基本的描述性统计。

resp["anninc"].describe()

这给了我基本的统计数据:

count     76310.000000
mean      43455.874862
std       33154.848314
min           0.000000
25%       20140.000000
50%       34980.000000
75%       56710.000000
max      152884.330000
dtype: float64

但是有一个注意点。由于样本的构建方式,需要对受访者数据进行加权调整,以便在进行分析时不是每个人都被视为"平等的"。在数据帧中,我有另一列(称为tufnwgrp)表示应在分析期间应用于每个记录的权重。

在我之前的SAS生活中,大多数程序都有处理此类加权数据的选项。例如,通过标准proc univariate处理数据以得到相同结果,看起来是这样的:

proc univariate data=resp;
  var anninc;
  output out=resp_univars mean=mean median=50pct q1=25pct q3=75pct min=min max=max n=count;
run;

使用加权数据进行相同分析的结果大致如下:

proc univariate data=resp;
  var anninc;
  weight tufnwgrp;
  output out=resp_univars mean=mean median=50pct q1=25pct q3=75pct min=min max=max n=count
run;

在Pandas中,像describe()这样的方法是否有类似的加权选项可用?


我不知道DataFrame上是否有这样的方法。您希望像计数和分位数之类的东西发生变化吗?还是只有均值和标准差?您可以先应用加权,然后在结果系列上调用describe吗? - TomAugspurger
谢谢TomAuspurger……这正是我怀疑的,但我希望避免编写额外代码……我希望它适用于所有度量标准。 - Chris Chapo
其实这不需要太多的工作。我认为(df['anninc'] * df['tufnwgrp']).describe()就可以解决问题了。你可能需要在某个时候转换数据类型。 - TomAugspurger
我认为它并不能完全达到效果,因为我在回答Phillip Cloud的问题时已经解释了。这可能需要更多的工作。 - etna
创建Python Pandas中的部分SAS Proc Summary替代方案 - JohnE
1个回答

7

有一个统计学和计量经济学库(statsmodels)似乎可以处理这个问题。这里有一个示例,扩展了@MSeifert在类似问题上的回答here

df=pd.DataFrame({ 'x':range(1,101), 'wt':range(1,101) })

from statsmodels.stats.weightstats import DescrStatsW
wdf = DescrStatsW(df.x, weights=df.wt, ddof=1) 

print( wdf.mean )
print( wdf.std )
print( wdf.quantile([0.25,0.50,0.75]) )

67.0
23.6877840059
p
0.25    50
0.50    71
0.75    87

虽然我不使用SAS,但是这个命令与Stata命令给出了相同的答案:

sum x [fw=wt], detail

Stata实际上有几个权重选项,在这种情况下,如果您指定aw(分析权重)而不是fw(频率权重),则会得到稍微不同的答案。此外,Stata要求fw为整数,而DescrStatsW允许非整数权重。权重比您想象中的要复杂...这开始变得繁琐,但是这里有一次对计算标准偏差的加权问题进行了很好的讨论。
另请注意,DescrStatsW似乎没有包含最小值和最大值的函数,但只要您的权重非零,这应该不是问题,因为权重不会影响最小值和最大值。但是,如果您有一些零权重,拥有加权最小值和最大值可能很好,但在pandas中也很容易计算:
df.x[ df.wt > 0 ].min()
df.x[ df.wt > 0 ].max()

如果你需要以组为单位进行操作,你可以随时使用 .apply。但如果你想避免使用 .apply,请参考这个答案 https://stackoverflow.com/questions/62723290/getting-descriptive-statistics-with-analytic-weighting-using-describe-in-pyt/62748369#62748369。 - jtorca

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接