如何在 Pandas/Numpy 中使用 dateOffset 对日内时间序列数据进行重新采样?

Posted

技术标签:

【中文标题】如何在 Pandas/Numpy 中使用 dateOffset 对日内时间序列数据进行重新采样?【英文标题】:How to do resample of intraday timeseries data with dateOffset in Pandas/Numpy? 【发布时间】:2014-11-12 03:00:32 【问题描述】:

我正在处理期货数据,即当天在 00:00:00 之前开始。考虑到日期偏移量,我需要将 1 分钟数据重新采样为 1 小时数据。我们来看一个例子:

df1 - 1分钟数据

                        Open     High      Low    Close
2005-09-06 17:27:00  1234.75  1234.75  1234.75  1234.75
2005-09-06 17:28:00  1234.75  1234.75  1234.75  1234.75
2005-09-06 17:29:00  1234.75  1234.75  1234.75  1234.75
2005-09-06 17:30:00  1234.75  1234.75  1234.50  1234.50
2005-09-06 18:01:00  1234.50  1234.50  1234.25  1234.50
2005-09-06 18:02:00  1234.50  1234.50  1234.50  1234.50
2005-09-06 18:03:00  1234.50  1234.50  1234.50  1234.50
2005-09-06 18:04:00  1234.50  1234.50  1234.50  1234.50
2005-09-06 18:05:00  1234.50  1234.50  1234.25  1234.25

这就是常规重采样会发生的情况:

conversion = 'Open': 'first', 'High': 'max', 'Low': 'min', 'Close': 'last'

In [77]: normal_resample = df1.resample(rule='60Min', how=conversion)
In [78]: normal_resample
Out[79]: 
                        Open     High      Low    Close
2005-09-06 17:00:00  1234.75  1234.75  1234.50  1234.50
2005-09-06 18:00:00  1234.50  1234.50  1234.25  1234.25

这是偏移量的所需输出:

conversion = 'Open': 'first', 'High': 'max', 'Low': 'min', 'Close': 'last'

In [77]: offset_resample = df1.resample(rule='60Min', how=conversion) + offset:18:00
In [78]: offset_resample
Out[79]: 
                        Open     High      Low    Close
2005-09-06 17:00:00  1234.75  1234.75  1234.50  1234.50
2005-09-07 18:00:00  1234.50  1234.50  1234.25  1234.25

注意我想要的是如何指定新的一天从 '18:00:00' 开始,而不是午夜。

我做了什么:我有一个包含偏移量的公式,对每日数据进行重采样,但我不知道如何使其适应日内重采样。

def resample_day(df):
    df.index = pd.DatetimeIndex(df.index)
    df = df.between_time('18:00', '16:00', include_start=True, include_end=True)
    proxy = df.index + pd.DateOffset(hours=6)  # This is the piece that does the trick
    result = df.groupby(proxy.date).agg(
        'Open': 'first', 'High': 'max', 'Low': 'min', 'Close': 'last')
    result = result.reindex(columns=['Open', 'High', 'Low', 'Close'])
    return result

另外,suggested here 是什么,至少对我来说不起作用。

感谢您的意见。

【问题讨论】:

+1 重采样技巧,非常棒! 【参考方案1】:

您可以只添加一天(如果时间超过下午 5 点):

In [11]: df1.index.time > datetime.time(17)
Out[11]: array([False,  True], dtype=bool)

In [12]: df1.index + np.where((df1.index.time > datetime.time(17)), pd.offsets.Day(1).nanos, 0)
Out[12]:
<class 'pandas.tseries.index.DatetimeIndex'>
[2005-09-06 17:00:00, 2005-09-07 18:00:00]
Length: 2, Freq: 60T, Timezone: None

【讨论】:

您的建议似乎是一个很好的解决方法,但我收到了这个疯狂的错误:文件“”,第 1 行,在 df1.index + np.where ((df1.index.time > datetime.time(17)), pd.offsets.Day(1).nanos, 0) 文件 "C:\Users\Hernan\Anaconda\lib\site-packages\pandas\tseries\ index.py”,第 619 行,在 add 中引发 TypeError(other) TypeError: [0 0 86400000000000 ..., 0 0 0] 您使用的是旧版本的 pandas / numpy 吗?也许试试:pd.to_datetime(df1.index.values + np.where((df1.index.time &gt; datetime.time(17)), pd.offsets.Day(1).nanos, 0)) 或者可能是df1.index.values.astype('int64') pd.__version__'0.14.0', numpy.version.version '1.8.1' pd.to_datetime(df1.index.values + np.where((df1.index.time > datetime.time(17)), pd.offsets.Day(1).nanos, 0) ) 给我一个空的df。还有df1.index.values.astype('int64')...不知道怎么用这个。 @hernanavella 很有趣,也许这在 0.14.1 中已修复。所以上面的目标是以纳秒为单位将 datetime 转换为 int64,然后将其以纳秒 (astype('int64')) 的形式添加到 datetime64 中,然后包装到 to_datetime 以将纳秒转换为 datetime64。如果不清楚,您必须将结果(新的 DatetimeIndex)设置为 df1.index,即 df1.index = pd.to_datetime(...)

以上是关于如何在 Pandas/Numpy 中使用 dateOffset 对日内时间序列数据进行重新采样?的主要内容,如果未能解决你的问题,请参考以下文章

如何确定 Pandas/NumPy 中的列/变量是不是为数字?

如何将一系列数组转换为 pandas/numpy 中的单个矩阵?

如何在 pandas/numpy 中将值扩展到下一个非空值? [复制]

在 python 中使用 pandas,numpy 是不是有 pyspark.ml.feature StringIndexer 的替代方法?

pandas -- numpy++

pandas -- numpy++