熊猫以“季节性”频率重新取样

时间:2014-04-03 11:07:27

标签: python pandas time-series offset

在我的领域(天然气市场),一个季节是一个跨越2个季度的时期。 4月到9月(包括两者)就是我们所说的夏天,其余的都是冬天。

使用pandas,我试图将每日数据重新采样到季节,并且根据每日指数的开始,我似乎得到不同的结果。基本上,如果开始是在Q2或Q4,重新采样按预期工作,但如果索引在Q1或Q3中开始则不行。请注意,结束日期不会发生同样的情况,因为重新采样似乎在那里表现正确。

无论如何这里是一个示例代码:

import pandas as pd
import numpy as np


april_start_dates = pd.DatetimeIndex(freq = 'D', start = '2014-04-01', end = '2015-01-01')

good_case = pd.DataFrame(np.random.randn(april_start_dates.size), index = april_start_dates)

for d in good_case.resample('2QS-APR').index:
    print d.strftime('%d-%b-%Y')

'''
Correct output
01-Apr-2014
01-Oct-2014
'''

jan_start_dates = pd.DatetimeIndex(freq = 'D', start = '2014-01-01', end = '2015-01-01')

bad_case = pd.DataFrame(np.random.randn(jan_start_dates.size), index = jan_start_dates)

for d in bad_case.resample('2QS-APR').index:
    print d.strftime('%d-%b-%Y')

'''
Wrong output ?      Expected
01-Jan-2014         01-Oct-2013
01-Jul-2014         01-Apr-2014
01-Jan-2015         01-Oct-2014
'''

good_case有正确的日期,一个在四月,另一个在十月:

正确输出
01-APR-2014
2014年10月1日

但对于bad_case来说情况并非如此,其中日期不会在4月或10月出现,正如人们对锚定的偏移'2QS-APR'所期望的那样。 我期望看到bad_case是这个(第一个日期是10月13日,它是包含2014年1月1日的季节性时期的开始):

预期
01-OCT-2013
01-APR-2014
2014年10月1日

请注意,平均值也是错误的,因此使用loffset移动标签似乎不是一个足够好的选项。

我错过了什么吗?我能做些什么来得到我想要的东西?

感谢。

1 个答案:

答案 0 :(得分:1)

看起来这对我来说可能是个错误。我提交了issue

它正在发生的事情是它认为1月份正在抵消。我不认为这应该是真的,如果偏移中的n应该像你期望的那样工作。

 [~/]
 [18]: from pandas.tseries.offsets import QuarterBegin

 [~/]
 [19]: ts = pd.Timestamp('2014-1-1')

 [~/]
 [20]: offset = QuarterBegin(2, startingMonth=4)

 [~/]
 [21]: offset.onOffset(ts)
 [21]: True

你可以通过这样做获得预期的输出,但它是一个黑客,我不希望它在未来工作。我不确定n是否正常工作(或者我们都误解了它应该如何运作)

 bad_case.resample('2Q-APR').shift(-1, freq='2QS-APR')