【问题标题】:Calculating multi year 5-day running percentile计算多年 5 天运行百分位数
【发布时间】:2021-10-23 09:57:54
【问题描述】:

我需要根据多年数据计算每个日历日的 3 天运行 90% 值。我有 30 年的每日数据集看起来像这样,

            year    month   day  value
DATE                    
01/01/1980  1980    1       1    12.3957
02/01/1980  1980    1       2    8.2678
03/01/1980  1980    1       3    11.9438
04/01/1980  1980    1       4    8.8035
05/01/1980  1980    1       5    2.749
...             ... ... ...
27/01/2010  2010    1       27   4.1186
28/01/2010  2010    1       28   5.9619
29/01/2010  2010    1       29   8.8146
30/01/2010  2010    1       30   12.9397
31/01/2010  2010    1       31   11.8427

为了计算 1 月 1 日的第 90 个百分位值,我必须选择以 1 月 1 日为中心的 3 天窗口,为期 30 年。因此,我每天将有 90 (3*30) 个数据点。我可以计算百分位数并将其记录为该中心日的第 90 个百分位数。然后,我将通过移动 3 天窗口来重复此过程,直到我有一个新的数据框,其中填充了从 1 月 1 日到 12 月 31 日的每一天的百分位值。

问题是,我的数据集有时是一个正常的日历年(即 365/366 天),有时只有 365 天,或 360 天(12 个月*30 天)。我正在删除闰日,但我不知道哪个数据集是哪个。

我尝试迭代数天,但当没有 2 月 29 日或 1 月 31 日时出现问题。我尝试使用 for 循环对多个条件进行切片,但遇到了同样的问题。

我不知道如何选择 30 年的 3 天移动窗口并计算百分位数。

任何帮助将不胜感激!

【问题讨论】:

    标签: python pandas datetime indexing percentile


    【解决方案1】:

    我已经设法解决了这个问题。首先,我放弃了 2 月 29 日。因此,我将拥有一个 365 天或 360 天的数据集。然后,我将日期时间索引更改为字符串。

    df.index = df.index.strftime('%m-%d')
    

    我使用枚举唯一索引值来循环遍历所有日子。我使用 if-else 块能够选择以一年的第一天和最后两天为中心的 5 天窗口,否则 start 将大于 end

    对于 1 月 1 日,应该是

    current = '01-01'
    start = '12-30'
    end = '01-03'
    

    所以,我同时使用了or |and & 运算符来选择日期。

    90p = {}
    for count, date in enumerate(df.index.unique()):
        start = df.index[count-2]
        end = df.index[count+2]
        current = df.index[count]
        print("My date is %s, 2 day before is %s and 2 day later is %s" % (current, start, end))
    
        # day[0]
        if count == 0:
            temp = df.loc[((df.index >= current) & (df.index <= end)) | ((df.index >= df.index[count - 2]) & (df.index <= df.index[count - 1]))]
            90p[date] = temp.value.quantile(0.9)
        
        # day[1]
        elif count == 1:
            temp = df.loc[((df.index >= df.index[count - 1]) & (df.index <= end)) | ((df.index >= df.index[count - 2]) & (df.index <= df.index[count - 2]))]
            90p[date] = temp.value.quantile(0.9)
        
        # day[-2]
        elif count == len(df.index.unique()) - 2:
            temp = df.loc[((df.index >= df.index[count - 2]) & (df.index <= df.index[count + 1])) | ((df.index >= df.index[count + 2]) & (df.index <= df.index[count + 2]))]
            90p[date] = temp.value.quantile(0.9)
    
        # day[-1]
        elif count == len(df.index.unique()) - 1:
            temp = df.loc[((df.index >= df.index[count - 2]) & (df.index <= df.index[count])) | ((df.index >= df.index[count + 1]) & (df.index <= df.index[count + 2]))]
            90p[date] = temp.value.quantile(0.9)
        
        # day[2:-2]
        else:
            temp = df.loc[(df.index >= start) & (df.index <= end)]  
            90p[date] = temp.value.quantile(0.9)
    

    【讨论】:

      猜你喜欢
      • 2011-12-29
      • 2013-06-20
      • 2016-01-01
      • 2016-07-28
      • 2017-08-29
      • 2012-10-28
      • 2021-02-26
      • 1970-01-01
      • 2013-08-31
      相关资源
      最近更新 更多