如何构建自定义 pandas.tseries.offsets class?

How to build custom pandas.tseries.offsets class?

我想找到一种方法在交易时间内以 1 秒的频率构建自定义 pandas.tseries.offsets class。这里的主要要求是时间偏移对象足够聪明,可以知道“2015-06-18 16:00:00”的下一秒是“2015-06-19 09:30:00 或 [=43=” ]',并且根据这两个时间戳计算的时间增量将恰好为 1s(自定义偏移量 1s,类似于工作日频率的 BDay(1)),而不是关闭时间的持续时间。

原因是在绘制几个交易日的盘中数据pd.Series时,请看下面的模拟示例,收盘和第二天之间有很多'step line'(线性插值)开盘价代表收盘时间的持续时间。有没有办法摆脱这个?我查看了 pandas.tseries.offsets 的源代码,发现 pd.tseries.offsets.BusinessHourpd.tseries.offsets.BusinessMixin 可能有帮助,但我不知道如何使用它们。

import pandas as pd
import numpy as np
from pandas.tseries.holiday import USFederalHolidayCalendar
from pandas.tseries.offsets import CustomBusinessDay

# set as 'constant' object shared by all codes in this script
BDAY_US = CustomBusinessDay(calender=USFederalHolidayCalendar())
sample_freq = '5min'
dates = pd.date_range(start='2015-01-01', end='2015-01-31', freq=BDAY_US).date
# exculde the 09:30:00 as it is included in the first time bucket
times = pd.date_range(start='09:30:00', end='16:00:00', freq=sample_freq).time[1:]
time_stamps = [dt.datetime.combine(date, time) for date in dates for time in times]
s = pd.Series(np.random.randn(len(time_stamps)).cumsum() + 100, index=time_stamps)

s.plot()

另一种我能想到的部分解决这个问题的方法是首先reset_index()获取每行的默认连续整数索引,然后计算连续整数索引之间的差异作为时间(以秒为单位)过去。将整数索引绘制为 x 轴,然后将它们重新标记为适当的时间标签。有人可以告诉我如何使用 matplotlib 吗?

感谢杰夫的评论。我只是检查了 BusinessHour() 的在线文档,发现它可能对我的情况有用。另一个后续问题: BusinessHour 是小时频率,有没有办法让它成为 1s 频率?另外,如何将它与 CustomBusinessDay 对象结合起来?

使用BusinessHour()

from pandas.tseries.offsets import *
bhour = BusinessHour(start='09:30', end='16:00')
time = pd.Timestamp('2015-06-18 15:00:00')
print(time)
2015-06-18 15:00:00
# hourly increment works nicely
print(time + bhour * 1)
2015-06-19 09:30:00
# but not at minute or second frequency
print(time + Minute(61))
2015-06-18 16:01:00
print(time + Second(60*60 + 1))
2015-06-18 16:00:01

非常感谢,如有任何帮助,我们将不胜感激。

正如我在评论中提到的,您可能有两个不同的问题

  1. 您需要能够在没有长线性插值的情况下绘制仅业务时间的时间序列。
  2. 您需要一个可以忽略非业务时间的日期时间算术(以秒为单位)的对象

我已经给出了一个占 1 的解决方案,因为这似乎是您的直接问题。如果您需要 2 个,或两者都需要 - 请在评论中告诉我们:

1。绘制相邻工作日的点

matplotlib 中的大多数图表都可以通过 ticker API. I'll adapt this example 将索引格式化程序应用于坐标轴以适合您的情况

import pandas as pd
import numpy as np
from pandas.tseries.holiday import USFederalHolidayCalendar
from pandas.tseries.offsets import CustomBusinessDay
import datetime as dt
import matplotlib.pyplot as plt
import matplotlib.ticker as ticker

# set as 'constant' object shared by all codes in this script
BDAY_US = CustomBusinessDay(calender=USFederalHolidayCalendar())
sample_freq = '5min'
dates = pd.date_range(start='2015-01-01', end='2015-01-31', freq=BDAY_US).date
# exculde the 09:30:00 as it is included in the first time bucket
times = pd.date_range(start='09:30:00', end='16:00:00', freq=sample_freq).time[1:]
time_stamps = [dt.datetime.combine(date, time) for date in dates for time in times]
s = pd.Series(np.random.randn(len(time_stamps)).cumsum() + 100, index=time_stamps)

data_length = len(s)
s.index.name = 'date_time_index'
s.name='stock_price'
s_new = s.reset_index()

ax = s_new.plot(y='stock_price') #plot the data against the new linearised index...

def format_date(x,pos=None):
    thisind = np.clip(int(x+0.5), 0, data_length-1)
    return s_new.date_time_index[thisind].strftime('%Y-%m-%d %H:%M:%S')

ax.xaxis.set_major_formatter(ticker.FuncFormatter(format_date))

fig = plt.gcf()
fig.autofmt_xdate()

plt.show()

这给出了如下输出,首先以自然比例缩小,然后放大,以便您可以看到星期五 16:00 和星期一 09:00

之间的过渡