在Pandas中,是否可以使用searchsorted处理MultiIndex索引?

3
我有一个具有MultiIndex索引的DataFrame。可以按照以下方式重新生成它:
import pandas as pd
import numpy as np
from numpy.random import randn as randn
from numpy.random import randint as randint
from datetime import datetime
# setup data
obs1 = [ob if ob > 0 else ob *-1 for ob in randn(10)*100]
obs2 = [randint(1000) for i in range(10)]
labels = ['A12', 'B12', 'A12', 'A12', 'A12','B12', 'A12','B12', 'A13', 'B13']
dates = [datetime(2012, 11, i) for i in range(1,11)]
dates[0] = dates[1]
dates[5] = dates[6]
# setup index and dataframe
m_idx = pd.MultiIndex.from_tuples(zip(dates, labels), names=['date', 'label'])
data_dict = {'observation1':obs1, 'observation2':obs2}
df = pd.DataFrame(data_dict, index=m_idx)

输出:

In [17]: df
Out[17]: 
                  observation1  observation2
date       label                            
2012-11-02 A12       79.373668           224
           B12      130.841316           477
2012-11-03 A12       45.312814           835
2012-11-04 A12      163.776946           623
2012-11-05 A12      115.449437           722
2012-11-07 B12       38.537737           842
           A12       84.807516           396
2012-11-08 B12       35.186265           707
2012-11-09 A13       60.171620           336
2012-11-10 B13      123.750614           540

相关日期:

dates_of_interest = [datetime(2012,11,1), datetime(2012,11,6)]

我有兴趣创建一个包含以下条件子集的数据框:
  • 日期最接近感兴趣日期之一
  • 标签字符串中包含 'A'
因此,我的子索引结果将如下所示:
                  observation1  observation2
date       label                            
2012-11-02 A12       79.373668           224
2012-11-07 A12       84.807516           396

理想情况下,我希望能够获取所有“接近”条件的观察数据,以便返回的数据集可能如下所示:
                  observation1  observation2
date       label                            
2012-11-02 A12       79.373668           224
2012-11-05 A12      115.449437           722
2012-11-07 A12       84.807516           396

但是起初,我只想得到第一个结果。我猜我需要使用searchsort和asof,但我不太确定如何在MultiIndex中实现。有人知道如何从这里开始吗?

敬礼

1个回答

2

使用 Series.asof 是一种自然的方法,但我看到了一些缺点:

  • 您正在寻找一个接近的时间戳,而asof搜索最新的时间戳。 在您的示例中,如果您搜索datetime(2012, 11, 1)(早于df中的任何条目),您将得到一个NaN
  • 它只适用于时间序列,因此您必须对DataFrame应用reset_index, 然后选择某个任意列作为时间序列。换句话说,它使您的代码有点笨拙和复杂。

这里是一个更健壮的替代方案,解决了您的第一个任务,即使用numpy.searchsorted搜索时间戳索引以获取近似命中:

import numpy as np

# it is important that df is sorted by date
df.sort_index(inplace=True)

dates_ix = df.index.levels[0]
nearest_date = lambda date: dates_ix[np.searchsorted(dates_ix, date)]
approx_dates = map(nearest_date, dates_of_interest)
# select the desired entries in the index
df.select(lambda (date, label): (date in approx_dates and 
                                 label.find('A')!=-1))

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接