填补MultiIndex Pandas Dataframe中的日期空白
我想修改一个熊猫MultiIndex
DataFrame,以使每个索引组都包括指定范围之间的日期。我希望每个小组使用值0(或NaN
)填写缺少的日期2013-06-11至2013-12-31
。
Group A, Group B, Date, Value
loc_a group_a 2013-06-11 22
2013-07-02 35
2013-07-09 14
2013-07-30 9
2013-08-06 4
2013-09-03 40
2013-10-01 18
group_b 2013-07-09 4
2013-08-06 2
2013-09-03 5
group_c 2013-07-09 1
2013-09-03 2
loc_b group_a 2013-10-01 3
我已经看到了有关reindex
ing的一些讨论,但这是针对简单(非分组)时间序列数据的。
是否有捷径可寻?
以下是我为实现此目的所做的一些尝试。例如:通过堆叠后['A', 'B']
,我便可以重新索引。
df = pd.DataFrame({'A': ['loc_a'] * 12 + ['loc_b'],
'B': ['group_a'] * 7 + ['group_b'] * 3 + ['group_c'] * 2 + ['group_a'],
'Date': ["2013-06-11",
"2013-07-02",
"2013-07-09",
"2013-07-30",
"2013-08-06",
"2013-09-03",
"2013-10-01",
"2013-07-09",
"2013-08-06",
"2013-09-03",
"2013-07-09",
"2013-09-03",
"2013-10-01"],
'Value': [22, 35, 14, 9, 4, 40, 18, 4, 2, 5, 1, 2, 3]})
df.Date = df['Date'].apply(lambda x: pd.to_datetime(x).date())
df = df.set_index(['A', 'B', 'Date'])
dt_start = dt.datetime(2013,6,1)
all_dates = [(dt_start + dt.timedelta(days=x)).date() for x in range(0,60)]
df2 = df.unstack(['A', 'B'])
df3 = df2.reindex(index=all_dates).fillna(0)
df4 = df3.stack(['A', 'B'])
## df4 is about where I want to get, now I'm trying to get it back in the form of df...
df5 = df4.reset_index()
df6 = df5.rename(columns={'level_0' : 'Date'})
df7 = df6.groupby(['A', 'B', 'Date'])['Value'].sum()
最后几行让我有些难过。我希望df6
我可以简单地set_index
回到['A', 'B',
'Date']
,但是不会将值分组,因为它们在初始df
DataFrame中分组了。
关于如何重新索引未堆叠的DataFrame,重新堆叠以及使DataFrame与原始格式相同的任何想法?
-
您不清楚确切的失踪日期。我只是假设您要填写
NaN
在其他地方 确实 有观察到的任何日期。如果此假设有误,则必须修改我的解决方案。旁注:添加一行以创建
DataFrame
In [55]: df = pd.DataFrame({'A': ['loc_a'] * 12 + ['loc_b'], ....: 'B': ['group_a'] * 7 + ['group_b'] * 3 + ['group_c'] * 2 + ['group_a'], ....: 'Date': ["2013-06-11", ....: "2013-07-02", ....: "2013-07-09", ....: "2013-07-30", ....: "2013-08-06", ....: "2013-09-03", ....: "2013-10-01", ....: "2013-07-09", ....: "2013-08-06", ....: "2013-09-03", ....: "2013-07-09", ....: "2013-09-03", ....: "2013-10-01"], ....: 'Value': [22, 35, 14, 9, 4, 40, 18, 4, 2, 5, 1, 2, 3]}) In [56]: In [56]: df.Date = pd.to_datetime(df.Date) In [57]: df = df.set_index(['A', 'B', 'Date']) In [58]: In [58]: print(df) Value A B Date loc_a group_a 2013-06-11 22 2013-07-02 35 2013-07-09 14 2013-07-30 9 2013-08-06 4 2013-09-03 40 2013-10-01 18 group_b 2013-07-09 4 2013-08-06 2 2013-09-03 5 group_c 2013-07-09 1 2013-09-03 2 loc_b group_a 2013-10-01 3
要填充未观察到的值,我们将使用
unstack
和stack
方法。取消堆叠将创建NaN
我们感兴趣的s,然后将它们堆叠起来使用。In [71]: df.unstack(['A', 'B']) Out[71]: Value A loc_a loc_b B group_a group_b group_c group_a Date 2013-06-11 22 NaN NaN NaN 2013-07-02 35 NaN NaN NaN 2013-07-09 14 4 1 NaN 2013-07-30 9 NaN NaN NaN 2013-08-06 4 2 NaN NaN 2013-09-03 40 5 2 NaN 2013-10-01 18 NaN NaN 3 In [59]: df.unstack(['A', 'B']).fillna(0).stack(['A', 'B']) Out[59]: Value Date A B 2013-06-11 loc_a group_a 22 group_b 0 group_c 0 loc_b group_a 0 2013-07-02 loc_a group_a 35 group_b 0 group_c 0 loc_b group_a 0 2013-07-09 loc_a group_a 14 group_b 4 group_c 1 loc_b group_a 0 2013-07-30 loc_a group_a 9 group_b 0 group_c 0 loc_b group_a 0 2013-08-06 loc_a group_a 4 group_b 2 group_c 0 loc_b group_a 0 2013-09-03 loc_a group_a 40 group_b 5 group_c 2 loc_b group_a 0 2013-10-01 loc_a group_a 18 group_b 0 group_c 0 loc_b group_a 3
根据需要重新排列索引级别。
我必须将其滑到
fillna(0)
中间,以免NaN
s掉落。
stack
确实有一个dropna
论点。我认为将其设置为false将保留所有NaN
行。可能是个错误?