根据Pandas with Groupby

时间:2016-03-05 21:53:57

标签: python pandas

我有5年的S& P 500数据我试图分组到特定的时间块来运行一些分析。我的数据以5分钟为增量。在将其读入一个名为日期的DataFrame后,我想我可以将它组合成块,包含连续的行,按Globex开放和关闭的时间增量每个交易日。 Globex开放时间为太平洋标准时间下午3:00(15:00),收盘时间为太平洋标准时间下午1:15(13:15),22.25小时后。因此,我希望将数据从下午3点开放到下午1:15关闭 - 每块大约275行。

困难在于,“交易日”跨越2个不同的日期,例如,会话在星期日3-6-2016 在15:00开始,并在星期一,3结束-7-2016 在13:15。我无法通过'Date'列进行分组,因为当我需要数据块跨越两个日期时,所有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',问题在于它使用了今天的日期。这显然对我不起作用,因为我的数据是历史数据,日期和时间是历史价格的参考 我试图将“时间”列更改为日期时间对象的原因是我认为我可以将其切片到组合操作期间所需的块中:

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

这产生了错误:

IndexError: invalid slice

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

谢谢, 安娜

1 个答案:

答案 0 :(得分:2)

这实际上非常复杂。

首先,您可以按如下方式转换时间:

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

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

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

这里我们创建一个函数,而不是返回分组条上的open,high,low,close等:

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.

现在我们根据market_open中的更改(即关于True / False标志的更改)进行groupby,然后我们将函数应用于这些分组结果。

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