查询pandas MultiIndex的正确方法

时间:2016-03-19 12:41:29

标签: pandas

我有一个巨大的数据框(1300万行)库存和股票价格。我已使用MultiIndex(['stock', 'date'])对其进行索引,其中date已被解析为{ {1}}。

这意味着我可以轻松地根据库存DateTime以及特定日期df.loc['AAPL']选择价格数据。

我想知道的是,什么是在特定日期获得所有股票价格的最快和最优雅的访问者(即如果指数被反转)。

目前我正在使用df.loc['AAPL'].loc['2015-05-05'] - 这是正确的方法吗?是否有更好/更清洁/更快的方式?

1 个答案:

答案 0 :(得分:4)

我认为你所做的很好,但也有其他方法。

>>> df = pd.DataFrame({ 
              'stock':np.repeat( ['AAPL','GOOG','YHOO'], 3 ),
              'date':np.tile( pd.date_range('5/5/2015', periods=3, freq='D'), 3 ),
              'price':(np.random.randn(9).cumsum() + 10) })

>>> df = df.set_index(['stock','date'])

                      price
stock date                 
AAPL  2015-05-05   8.538459
      2015-05-06   9.330140
      2015-05-07   8.968898
GOOG  2015-05-05   8.964389
      2015-05-06   9.828230
      2015-05-07   9.992985
YHOO  2015-05-05   9.929548
      2015-05-06   9.330295
      2015-05-07  10.676468

两次使用loc的标准方法

>>> df.loc['AAPL'].loc['2015-05-05']

将会做

>>> df.loc['AAPL','2015-05-05']

price    8.538459
Name: (AAPL, 2015-05-05 00:00:00), dtype: float64

而不是xs你可以使用IndexSlice。我认为2级xs更容易,但IndexSlice可能会好于2级。

>>> idx=pd.IndexSlice

>>> df.loc[ idx[:,'2015-05-05'], : ]

                     price
stock date                
AAPL  2015-05-05  8.538459
GOOG  2015-05-05  8.964389
YHOO  2015-05-05  9.929548

说实话,我认为绝对最简单的方法是使用日期或股票(或两者都不)作为索引,然后大多数选择都非常简单。例如,如果您完全删除索引,则可以毫不费力地按日期选择:

>>> df = df.reset_index()
>>> df[ df['date']=='2015-05-05' ]

   index stock       date      price
0      0  AAPL 2015-05-05   8.538459
3      3  GOOG 2015-05-05   8.964389
6      6  YHOO 2015-05-05   9.929548

使用3个股票和3000个日期(= 9000行)做一些快速计时,我发现一个简单的布尔选择(没有索引)比xs快35%,而xs比使用IndexSlice快35%左右。但是请参阅下面的杰夫评论,你应该期望布尔选择在更多行的情况下表现相对更差。

当然,您要做的最好的事情就是测试自己的数据,看看它是如何产生的。