使用“季节性”频率重采样Pandas

3 投票
1 回答
3938 浏览
提问于 2025-04-18 01:09

在我的领域(天然气市场),一个季节是指跨越两个季度的时间段。四月到九月(包括这两个月)被称为夏季,而剩下的时间则是冬季。

我在使用pandas的时候,想把每天的数据重新分组为季节,但根据每天数据的开始时间,我发现结果会有所不同。简单来说,如果开始时间在第二季度或第四季度,重新分组的结果是正常的,但如果开始时间在第一季度或第三季度,结果就不对了。值得注意的是,结束日期的处理是正常的。

下面是一个示例代码:

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
01-Oct-2014

但在bad_case中,日期没有落在四月或十月,这与预期的“2QS-APR”偏移不符。对于bad_case,我期望看到的是这样的结果(第一个日期是2013年10月,因为这是包含2014年1月1日的季节开始日期):

预期
01-Oct-2013
01-Apr-2014
01-Oct-2014

另外,平均值也不对,所以用loffset来调整标签似乎也不是一个好的解决办法。

我是不是漏掉了什么?我该怎么做才能得到我想要的结果?

谢谢。

1 个回答

2

看起来这可能是个bug。我已经在这里提交了一个问题

发生的情况是,它认为一月在偏移量上。我觉得这不应该是这样的,前提是偏移量中的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')

撰写回答