pandas index.asof with multiindex

时间:2014-11-21 18:24:56

标签: python pandas

我有每个实体的时间序列数据:

id  event_date  value
1   2013-12-21  3.82
1   2013-12-22  2.47
1   2013-12-25  2.13
1   2014-01-03  3.92
1   2014-01-04  2.48
2   2014-10-16  3.96
2   2014-10-17  3.61
2   2014-10-29  2.59
2   2014-11-05  3.64
2   2014-11-15  2.85

我把它放在带有多索引的数据框中:

               value
id event_date
1  2013-12-21   3.82
   2013-12-22   2.47
   2013-12-25   2.13
   2014-01-03   3.92
   2014-01-04   2.48
2  2014-10-16   3.96
   2014-10-17   3.61
   2014-10-29   2.59
   2014-11-05   3.64
   2014-11-15   2.85

我试图在每个id的系列中找到任意截止之前的最新日期(比如在2014-10-31或2014-09-30之前)。 index.asof或Series.asof似乎是我想要的,但我无法弄清楚如何将它与多个索引一起使用。对于'2014-10-30'的日期,我想要这个输出:

id  event_date
1   2014-01-04 00:00:00
2   2014-10-29 00:00:00

我可以通过循环第一级索引来到达那里,但似乎应该有更好的更多pandonic方式(完整的数据集非常大)而我只是错过了它。

In [10]: for idx in df.index.levels[0]:
   ....:     print idx, df.loc[idx].index.asof('2014-10-30')
   ....:
1 2014-01-04 00:00:00
2 2014-10-29 00:00:00

没有理由数据必须在这个多索引结构中,只是因为我有每个id的时间序列似乎有意义。时间排序,没有重复。

版本: 大熊猫:0.15.0 numpy:1.9.0

2 个答案:

答案 0 :(得分:1)

在我看来,@ gjreda的答案只是错过了你的截止过滤器,所以假设索引中的event_dateid 不是

cutoff = '2014-10-30'
df[df['event_date'] <= cutoff].groupby(['id'])['event_date'].last()

这给出了与之前相同的输出,但截止是任意的:

id
1    2014-01-04
2    2014-10-29
Name: event_date, dtype: datetime64[ns]

如果您仍想在索引中使用这些列,您可以这样做:

df[df.index.levels[1] <= cutoff].groupby(level=['id']).apply(lambda x: x.index.get_level_values(1).max())

顺便说一句.asof应用于groupby数据框时,评估整个索引而不是组的索引,因此asof的版本无法按预期工作:

df[df.index.levels[1] <= cutoff].groupby(level=[0]).apply(lambda x: x.index.levels[1].asof(cutoff))

返回:

id
1    2014-10-29
2    2014-10-29
dtype: datetime64[ns]

看起来它使用了所有组的最后一个真值。

答案 1 :(得分:0)

如果没有理由将它放在MultiIndex中,你可以这样做:

In [10]: df.reset_index(inplace=True)
In [11]: df.groupby('id')['event_date'].max()
Out[11]: 
id
1     2014-01-04
2     2014-11-15
Name: event_date, dtype: object

```