我有一个数据框,其中包含每组收入的观察数量:
INCAGG
1 6.561681e+08
3 9.712955e+08
5 1.658043e+09
7 1.710781e+09
9 2.356979e+09
我想计算收入中位数组。我是什么意思? 让我们从一个更简单的系列开始:
INCAGG
1 6
3 9
5 16
7 17
9 23
代表这组数字:
1 1 1 1 1 1
3 3 3 3 3 3 3 3 3
5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5
7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7
9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9
我可以重新订购
1 1 1 1 1 1 3 3 3 3 3 3 3 3 3 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 7 7 7 7 7
7 7 7 7 7 7 7 7 7 7 7 7 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9
这在视觉上就是我的意思 - 这里的中位数是 7
。
最佳答案
浏览了一个 numpy 示例后 here ,我认为 cumsum()
提供了一个很好的方法。假设您的计数列称为“wt”,这是一个在大多数情况下都有效的简单解决方案(请参阅下文以了解更通用的解决方案):
df = df.sort('incagg')
df['tmp'] = df.wt.cumsum() < ( df.wt.sum() / 2. )
df['med_grp'] = (df.tmp==False) & (df.tmp.shift()==True)
上面的第二行代码将中位数上方和下方的行分成几行。中值观察将在第一个 False
组中。
incagg wt tmp med_grp
0 1 656168100 True False
1 3 971295500 True False
2 5 1658043000 True False
3 7 1710781000 False True
4 9 2356979000 False False
df.ix[df.med_grp,'incagg']
3 7
Name: incagg, dtype: int64
当中位数唯一且通常不唯一时,这会很好地工作。仅当中位数不唯一且落在组的边缘时才会出现此问题。在这种情况下(有 5 个组和数百万/数十亿的权重),这真的不是问题,但这里有一个更通用的解决方案:
df['tmp1'] = df.wt.cumsum() == (df.wt.sum() / 2.)
df['tmp2'] = df.wt.cumsum() < (df.wt.sum() / 2.)
df['med_grp'] = (df.tmp2==False) & (df.tmp2.shift()==True)
df['med_grp'] = df.med_grp | df.tmp1.shift()
incagg wt tmp1 tmp2 med_grp
0 1 1 False True False
1 3 1 False True False
2 5 1 True False True
3 7 2 False False True
4 9 1 False False False
df.ix[df.med_grp,'incagg']
2 5
3 7
df.ix[df.med_grp,'incagg'].mean()
6.0
关于python - Pandas :分组观察的加权中位数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29678166/