我有每个实体的时间序列数据:
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
答案 0 :(得分:1)
在我看来,@ gjreda的答案只是错过了你的截止过滤器,所以假设索引中的event_date
和id
不是:
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
```