2016-03-05 158 views
2

我有5年的S & P 500数据,我试图将其分组到特定的时间块中以运行某些分析。我的数据以5分钟为增量。在将它读入一个名为“过时”的DataFrame中后,我想我可以将它分组为包含连续行的块,按照Globex每个交易日的打开和关闭之间的时间增量进行分组。 Globex开放时间为太平洋标准时间下午3:00(15:00),结束时间为太平洋标准时间下午1:15(13:15),22.25小时后。因此,我想将数据从下午3点开放到下午1点15分 - 每个块大约有275行。从DataFrame中选择CONSECUTIVE行,根据Pandas与Groupby列中的值

的困难是,“交易日”跨越2个不同的日期,为eaxmple,一个会议日2016年3月6日在15:00打开和关闭的周一,2016年3月7日在 13:15。我无法按'日期'列进行分组,因为当然,所有的3-6都将在一个块中,3-7在另一个块中,当我需要数据块跨越这两个日期时,为了获得整个 Globex日在一个块。

对于Pandas和Python我都不太熟悉,我不知道用什么方法将数据分组到我想要的块中。一旦数据被隔离,我想提取每个会话/块的高和低分为不同的列,并为15:05开放价格提供一个列。

这里是什么我的数据看起来像一个示例:

Date Time Open High Low Close Up Down 
0 2015-08-03 15:05 2073.50 2074.00 2073.25 2073.25 210 563 
1 2015-08-03 15:10 2073.25 2073.25 2072.25 2072.75 118 632 
2 2015-08-03 15:15 2072.75 2072.75 2072.25 2072.50 132 85 
3 2015-08-03 15:20 2072.50 2072.75 2072.25 2072.50 95 312 
4 2015-08-03 15:25 2072.50 2074.00 2072.50 2073.50 372 264 

本来,“日期”列中的值是这样的:2015年8月3日。我认为它可能不会被读为一个实际的日期对象,所以我使用to_datetime()更改了值,以使'Date'列的值像实际的日期对象一样读取,如上面的示例DataFrame中所示。

dated['Date'] =pd.to_datetime(dated['Date']) 

当我试图使用to_datetime(),它成功地改变从15:05到15:05:00的时间来改变在“时间”列中的值,但同时也增加了一天,所以它看起来像这样︰'2016-03-05 15:05:00',问题是它使用今天的日期为日期。这显然不适用于我,因为我的数据是历史数据,日期和时间是对历史价格的参考。
我试图在“时间”栏更改为datetime对象的原因是我想我可以把它切成我一个GROUPBY操作过程中需要的块:

dated = dated['Date'].groupby(dated['15:05' : '13:20']) 

这产生和错误:

IndexError: invalid slice 

所以我会很感激解决这个问题的任何帮助 - 指着我的研究的正确区域。我一直在逐一阅读熊猫文档,尝试不同的方法,但由于我不确定从哪一步开始,我一直在随机挑选主题阅读而没有找到答案。

感谢, 安娜

回答

1

这实际上是非常复杂的。

首先,你可以将你的时间如下:

df['Datetime'] = pd.to_datetime(df.Date + ' ' + df.Time) 

在这里,我将创建一个更大的样本datframe:

np.random.seed(0) 
idx = pd.date_range('2015-1-1', '2016-1-1', freq='5min') 
df = pd.DataFrame(np.random.randn(len(idx), 6),  
        columns=['Open', 'High', 'Low', 'Close', 'Up', 'Down']) 
df['Datetime'] = idx 

让我们添加一个布尔标志,以表明当市场是开放的。

# Create a market open flag. 
df['market_open'] = False 
mask = (df.Datetime.dt.time > dt.time(15)) | (df.Datetime.dt.time < dt.time(13, 15)) 
df.loc[mask, 'market_open'] = True 

在这里,我们创造出比回报功能的开放,高,低,关闭等对分组条:

def ohlc(df): 
    return (
     df.Datetime.iat[-1], # last timestamp in group. 
     df.Open.iat[0], # First Open. 
     df.High.max(), 
     df.Low.min(), 
     df.Close.iat[-1], # Last Close. 
     df.Up.sum(), 
     df.Down.sum(), 
     df.Close.count(), # Count number of closing bars. 
     df.market_open.iat[0]) # Take first True/False indicator. 

现在,我们做我们的GROUPBY基于在market_open变化 (即在真/假标志的变化),然后我们将我们的功能应用于这些分组结果。

bars = pd.DataFrame(
    zip(*df.groupby(
      (df.market_open != df.market_open.shift()) 
      .cumsum() 
      ).apply(ohlc))).T 

bars.columns = ['bar_close_time', 'Open', 'High', 'Low', 'Close', 'Up', 'Down', 'bar_count', 'market_open'] 

我们对开放式会议和非公开会议都有酒吧。当市场关闭时,我们可以删除这些。

# Remove bars when market is closed 
bars = bars[bars.market_open].iloc[:, :-1] 

>>> bars.tail() 
      bar_close_time  Open  High  Low  Close  Up  Down bar_count 
722 2015-12-28 13:10:00 1.23175 2.88569 -2.7143 -0.785648 -13.3166 14.6094  266 
724 2015-12-29 13:10:00 -0.900675 2.6483 -2.61698 -0.8265 0.825872 4.98565  266 
726 2015-12-30 13:10:00 1.65299 2.57881 -2.85199 -0.376141 -4.32867 3.62123  266 
728 2015-12-31 13:10:00 0.435619 2.93638 -2.74758 -0.461525 -20.0928 -15.8205  266 
730 2016-01-01 00:00:00 0.293165 2.39097 -2.1234 0.0684124 -7.83721 1.69182  108 
+0

谢谢亚历山大, 当我拿到这部分代码: '日[ 'markt_open'] = FALSE 面膜=(dated.Datetime.dt.time> dt.time(15)) | (datedted.Datetime.dt.time AnaB29

+0

进口日期时间为DT – Alexander

+0

喜亚历山大和感谢这么多的帮助, 仍是同样的错误:'AttributeError的:“据帧”对象有没有属性“datetime'' 进口调整: '进口大熊猫作为PD - 进口numpy的作为np - 导入日期时间为dt'。我也解决了我的错误。我在这里查找Datetime属性:[链接](http://pandas.pydata.org/pandas-docs/version/0.17.0/api.html#dataframe)但找不到文档。 我不知道我错过了什么。 – AnaB29