2017-05-05 74 views
4

我想用一個開始日期,結束日期和「粒度」大熊貓 - 使用指定的開始日期,結束日期和粒度

重新採樣日期時間索引的數據幀重新取樣數據幀說我有這個數據幀:

    value 
00:00, 01/05/2017 2 
12:00, 01/05/2017 4 
00:00, 02/05/2017 6 
12:00, 02/05/2017 8 
00:00, 03/05/2017 10 
12:00, 03/05/2017 12 

我想重新取樣,從06:00, 01/05/2017
18:00 02/05/2017用12小時「粒度」(這是和原來一樣在這裏爲簡便起見但不必須的)。我想結果是:

    value 
06:00, 01/05/2017 3 
18:00, 01/05/2017 5 
06:00, 02/05/2017 7 
18:00, 02/05/2017 9 

注意,值是值它們重疊的平均值(例如3 =平均(2,4))

我不確定如何做到這一點。

我第一次嘗試是:

def resample(df: DataFrame, start: datetime, end: datetime, granularity: timedelta) -> DataFrame: 
    result = df.resample(granularity).mean() 
    result = result[result.index <= end] 
    result = result[result.index >= start] 
    return result 

這適當修剪數據幀,並確保正確的粒度,但這樣的結果是不對齊的開始日期的結果:

    value 
12:00, 01/05/2017 4 
00:00, 02/05/2017 6 
12:00, 02/05/2017 8 

我的第二次嘗試使用base參數來移動數據:

def resample(df: DataFrame, start: datetime, end: datetime, desired_granularity: timedelta) -> DataFrame: 
    data_before_start = df[df.index <= start] 
    # Get the last index value before our start date 
    last_date_before_start = data_before_start.last_valid_index() 
    current_granularity_secs = seconds_between_measurements(df) 
    rule = str(int(desired_granularity.total_seconds())) + 'S' 
    base = current_granularity_secs - (start - last_date_before_start).total_seconds() 
    result = df.resample(rule, base=base).mean() 
    result = result[result.index < end] 
    result = result[result.index >= start] 
    return result 

這給了我:

    value 
06:00, 01/05/2017 4 
18:00, 01/05/2017 6 
06:00, 02/05/2017 8 
18:00, 02/05/2017 10 

這有正確的指標,但是,值從下一次測量之前和之後回填而不是從測量的平均值。

有沒有人有任何想法,我怎麼能達到我想要的?

預先感謝您的幫助,只是讓我知道如果我漏掉了任何關鍵的細節:)

編輯: 如果得到的意思是,讓這個非常棘手的,我可以在位在給定的時間之前使用該值來解決,類似於pad()。我目前的'最佳'解決方案給我後面的值,如回填()

回答

0

首先將您的end_start和end_date列定義爲datetime。 然後,您可以使用.resample兩次:

  • 在df.start_date以正填充
  • 在DF。與向後填充

然後end_date之間:

  • 保持行,其中起始日期< END_DATE
  • 串聯
  • 在每一行上應用一個函數來更新起始日期日期和結束日期:

這裏代碼:

df[["start_date","end_date"]] = df[["start_date","end_date"]].astype(np.datetime64) 
df1 = df.set_index("start_date").resample(freq).pad().reset_index() 
df2 = df.set_index("end_date").resample(freq).bfill().reset_index() 
df3 = pd.concat([df1, df2], ignore_index=True) 

def function(x, df1): 
    if x.name < df1.shape[0]: 
     x.end_date = x.start_date + pd.Timedelta(freq) 
    else: 
     x.start_date = x.end_date - pd.Timedelta(freq) 
    return x 

df3[ df3.start_date < df3.end_date ].apply(lambda x: function(x, df1), axis=1) 

大熊貓的文件說,應該可以直接重新採樣

df.resample(freq, on='start_date')

相關問題