基于前几年的数据,为pandas数据框的行计算百分位数

3

I have the following dataframe:

datetime       JD      YEAR    VAL 
2000-01-01      1      2000    0.5
2000-01-02      2      2000    1.2
2000-01-03      3      2000    2.1
2000-01-04      4      2000    3.4 
2000-01-05      5      2000    4.6
2000-01-06      6      2000    6.8
2000-01-07      7      2000    7.2
2000-01-08      8      2000    0.2
2000-01-09      9      2000    0.9
...
2010-12-31      365    2014    4.1

第一年是2000年,最后一年是2010年。没有闰年(即没有对应于2月29日的行),日期时间是索引列。
我想计算一个新的数据框,从2010年1月1日到2010年12月31日。它应该包含一个列,该列计算出2010年1月1日值(VAL)在由10个值组成的数组(2000年1月1日、2001年1月1日...2009年1月1日)中的百分位数。同样地,2010年1月2日与之前年份的1月2日进行比较...
lyr = df.YEAR.max() # last year i.e. 2010
cdf = df[df.YEAR == lyr]# Latest year dataframe
pdf = df[df.index.year < lyr] # Previous years dataframe

pdf.groupby('JD')['VAL']
stats.percentileofscore(pdf['VAL'], cdf['VAL'])

然而,我不确定如何使代码正常运行。groupby 只返回组,而我需要一个值列表。

1个回答

7

使用一个小的示例数据帧进行设置:

np.random.seed(1234)
df = pd.DataFrame({ 'jd':  np.tile([1,2],3),
                    'yr':  np.repeat([2008,2009,2010],2),
                    'val': np.random.randn(6) })

然后就只需要一行代码:
df['pctile'] = df.groupby('jd')['val'].rank(pct=True)

以下是使用 sort_values(['jd','val']) 进行排序后的输出结果:

   jd       val    yr    pctile
4   1 -0.720589  2010  0.333333
0   1  0.471435  2008  0.666667
2   1  1.432707  2009  1.000000
1   2 -1.190976  2008  0.333333
3   2 -0.312652  2009  0.666667
5   2  0.887163  2010  1.000000

".rank(pct=True)" 不会返回真实的百分位数。它只是对值进行排名,但在计算百分位数时没有使用相同的逻辑。因此,这个答案是不正确的。 - bbennett36
@bbennett36 我不太明白你在说什么。排名和百分位数至少应该共享相同的排序方式。你认为在这个例子中正确的百分位数值是多少?如果你有更好或更正确的方法,请随意添加你自己的答案。 - JohnE
我猜答案在技术上并不是不正确,但是可能有必要补充一下这是计算百分位数的最近排名法。然而,在pandas中,“quantile”函数和numpy中默认的方法是“线性插值”方法。所以问题出在我使用了排名方法来计算一个数据集的百分位数,但是对于相同的数据,我使用了分位数,因为它们没有使用相同的方法。此外,排名方法不会总是在第50个排名处返回中位数,这就是我进行比较的地方。 - bbennett36
我正在寻找“线性插值”百分位数,而不是排名版本。由于原帖没有指定方法,因此我将取消踩。 - bbennett36
@bbennett36 谢谢,如果你认为公平的话,你有权利投反对票,但像你现在这样提出具体问题是更好的方式,在我的看法中。对于这个问题,我给一个赞,为了声望;-) - JohnE

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