1

たとえば、さまざまな間隔で取得された一連の日付とそれらの日の一連の数値があるとします。

説明のために、今日(9月29日)から3か月後(12月29日)までは毎日、2年後は3か月後、2年から10年までは四半期ごと、その後は毎年50回としましょう。年。

現在、要件は、すべての日付間隔の「パターン」に従うことですが、代わりに時系列は四半期の各終わり(つまり、3月31日、6月30日、9月30日、12月31日)に開始し、数値は線形補間されます。 -の間に。したがって、上記の例を使用すると、私の新しいシリーズは、9月30日(四半期の最初の終わり)から12月31日までの日次番号、2012年12月31日から2014年12月31日までの月次、2014年12月31日から2022年12月31日までの四半期、およびその後の年次である必要があります。古い時系列にない新しい時系列のすべての価格は、線形補間を使用して計算されます)。

それを効率的に行う方法はありますか?また、使用できるコード例はありますか?

あなたの助けに感謝します!

4

1 に答える 1

1

datetimeとだけでそれを行う方法を次に示しcalendarます。かなり長いですが、注意してください。

まず、目的の時系列を作成するメソッドが必要です

たとえば、1 月 31 日から 1 か月後の日付はどれですか? しかし、メソッドは次のようになります。

テストのために、日付に属するランダム値の生成を含めました。

from datetime import datetime, timedelta, date
import calendar
from random import random

def makeseries(startdate):
    datesA = [startdate] # collect the dates in this list
    valsA = [random()]   # and the randomly generated 'data' in this one
    date = startdate    

    # add days
    step = timedelta(1)
    while date - startdate <= timedelta(91):
        date += step
        datesA += [date]
        valsA += [random()]

    # add months
    step = timedelta(30)
    while date - startdate <= timedelta(2*365):
        if date.month in [1,3,5,7,8,10,12]:
            date += timedelta(1)
        elif date.month == 2:
            date -= timedelta(2)
        date += step
        datesA += [date]
        valsA += [random()]

    # add quarters
    step = timedelta(91)
    while date - startdate <= timedelta(int(365*10)):
        date += step
        if date.year % 4 == 0:
            date += timedelta(1)
        datesA += [date]
        valsA += [random()]

    # add years
    step = timedelta(365)
    while date - startdate <= timedelta(int(365*50)):
        date += step
        if date.year % 4 == 0:
            date += timedelta(1)
        datesA += [date]
        valsA += [random()]

    return datesA, valsA

次に、一連の日付で特定の日付に最も近い日付を見つける簡単な方法

def findIndexOfNearest(series, D):
    # returns the index of the date in series that is closest to, but greater than D
    for i, date in enumerate(series):
        if date > D:
            return i
    return None

2 つの時系列と、最初の系列のモック日付を生成します

thisyear = datetime.today().year
quarterEndMonth = (datetime.today().month+2)//3*3
quarterEndDay = calendar.monthrange(thisyear, quarterEndMonth)[1]

d1,v1 = makeseries(date.today())
d2,_ = makeseries(date(thisyear,quarterEndMonth, quarterEndDay))
v2 = []

timedeltasを使用して補間し、補間された値を出力します

for d in d2: 
    i = findIndexOfNearest(d1, d)
    if i:
        prev = d1[i-1]
        next = d1[i]
        prevRatio = 1-(d-prev).total_seconds()/(next-prev).total_seconds()
        nextRatio = 1-(next-d).total_seconds()/(next-prev).total_seconds()
        interp = prevRatio*v1[i-1] + nextRatio*v1[i]
        v2 += [interp]
        print("%s = %.2f * %s + %.2f * %s" % (d, prevRatio, prev, nextRatio, next))
        print("%17.2f * %10.2f + %.2f * %10.2f = %.2f" % \
               (prevRatio, v1[i-1], nextRatio, v1[i], interp))
    else: # date to be interpolated is past last original date
        v2 += [v1[-1]]
        print("%s = 1.00 * %s = %24.2f" % (d,d1[-1],v1[-1]))

出力例:

ここでは、元のシリーズが 3 か月間隔に切り替わったばかりで、1 つは 11 月に、もう 1 つは翌年の 2 月に行われます。補間する日付は 12 月です。

                     original           original
                      date                date
                        v                   v
2014-12-02 = 0.69 * 2014-11-04 + 0.31 * 2015-02-03
     ^       0.69 *       0.95 + 0.31 *       0.10 = 0.69
     |         ^           ^       ^           ^       ^
     |         |        original   |       original   interpolated 
date from      |         value     |         value       value
2nd series   weight              weight
于 2012-10-04T00:27:58.380 に答える