Python 熊猫等级索引的一级重新索引和填充
我有一个带有两级层次索引(“item_id”和“date”)的熊猫数据框架。每一行都有列,用于特定月份特定项目的各种度量。以下是一个示例:Python 熊猫等级索引的一级重新索引和填充,python,pandas,Python,Pandas,我有一个带有两级层次索引(“item_id”和“date”)的熊猫数据框架。每一行都有列,用于特定月份特定项目的各种度量。以下是一个示例: total_annotations unique_tags date item_id 2007-04-01 2 30 14 2007-05-01 2 32 16 2007-06-
total_annotations unique_tags
date item_id
2007-04-01 2 30 14
2007-05-01 2 32 16
2007-06-01 2 36 19
2008-07-01 2 81 33
2008-11-01 2 82 34
2009-04-01 2 84 35
2010-03-01 2 90 35
2010-04-01 2 100 36
2010-11-01 2 105 40
2011-05-01 2 106 40
2011-07-01 2 108 42
2005-08-01 3 479 200
2005-09-01 3 707 269
2005-10-01 3 980 327
2005-11-01 3 1176 373
2005-12-01 3 1536 438
2006-01-01 3 1854 497
2006-02-01 3 2206 560
2006-03-01 3 2558 632
2007-02-01 3 5650 1019
如您所见,并非每个项目的所有连续月份都有观察结果。我想做的是对数据帧重新编制索引,以便每个项目在指定范围内每个月都有行。现在,这对于任何给定的项目都很容易实现。因此,对于项目_id 99,例如:
baseDateRange = pd.date_range('2005-07-01','2013-01-01',freq='MS')
data.xs(99,level='item_id').reindex(baseDateRange,method='ffill')
但是使用这种方法,我必须遍历所有的item_id,然后将所有内容合并在一起,这似乎过于复杂了
那么,如何将其应用于完整的数据帧,对观察结果(以及项id索引)进行填充,以使每个项id都正确填充了baseDateRange中所有日期的行?基本上是针对要重新索引和ffill的每个组。apply获得一个数据帧,该数据帧的项id和日期仍在索引中,因此需要重置,然后设置并使用填充重新索引。 idx是上面的baseDateRange
In [33]: df.groupby(level='item_id').apply(
lambda x: x.reset_index().set_index('date').reindex(idx,method='ffill')).head(30)
Out[33]:
item_id annotations tags
item_id
2 2005-07-01 NaN NaN NaN
2005-08-01 NaN NaN NaN
2005-09-01 NaN NaN NaN
2005-10-01 NaN NaN NaN
2005-11-01 NaN NaN NaN
2005-12-01 NaN NaN NaN
2006-01-01 NaN NaN NaN
2006-02-01 NaN NaN NaN
2006-03-01 NaN NaN NaN
2006-04-01 NaN NaN NaN
2006-05-01 NaN NaN NaN
2006-06-01 NaN NaN NaN
2006-07-01 NaN NaN NaN
2006-08-01 NaN NaN NaN
2006-09-01 NaN NaN NaN
2006-10-01 NaN NaN NaN
2006-11-01 NaN NaN NaN
2006-12-01 NaN NaN NaN
2007-01-01 NaN NaN NaN
2007-02-01 NaN NaN NaN
2007-03-01 NaN NaN NaN
2007-04-01 2 30 14
2007-05-01 2 32 16
2007-06-01 2 36 19
2007-07-01 2 36 19
2007-08-01 2 36 19
2007-09-01 2 36 19
2007-10-01 2 36 19
2007-11-01 2 36 19
2007-12-01 2 36 19
根据杰夫的回答,我认为这是更可读的。由于只使用了液滴水平和重新索引方法,因此它的效率也大大提高
df = df.set_index(['item_id', 'date'])
def fill_missing_dates(x, idx=all_dates):
x.index = x.index.droplevel('item_id')
return x.reindex(idx, method='ffill')
filled_df = (df.groupby('item_id')
.apply(fill_missing_dates))
太棒了,但有两个澄清:首先,正如您所做的那样,我在item_id索引顶部留下了一个多余的item_id列。不过,我似乎可以通过将代码修改为
df.groupby(level='item'u id').apply(lambda x:x.reset\u index(level='item'u id',drop=True).reset\u index().set\u index('date').reindex(idx,method='ffill'))
。这看起来合理吗?第二:为什么date不再像在原始数据帧中那样在标题中显示为索引?我不认为这是个问题,但你能解释一下发生了什么吗?数据帧是否仍然具有层次索引或…?第一部分的答案是“是”,这是合理的,您可以删除重置索引以不具有dup。对于第二种情况,我认为apply对索引有点困惑,因为您聚合的方式(因此它删除了索引的名称)。您可以在应用程序内部执行另一个重置索引,然后在最后(在应用程序之后,.reset\u index(drop=True)。设置索引(['date','item\u id'))
,因此重置miHm…这实际上似乎不起作用(我认为日期索引适用于每个组,因此无法作为实际数据帧的索引访问).但我认为这在任何情况下都有效。谢谢。