填补MultiIndex Pandas Dataframe中的日期空白

发布于 2021-01-29 18:40:13

我想修改一个熊猫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

我已经看到了有关reindexing的一些讨论,但这是针对简单(非分组)时间序列数据的。

是否有捷径可寻?


以下是我为实现此目的所做的一些尝试。例如:通过堆叠后['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'],但是不会将值分组,因为它们在初始dfDataFrame中分组了。

关于如何重新索引未堆叠的DataFrame,重新堆叠以及使DataFrame与原始格式相同的任何想法?

关注者
0
被浏览
234
1 个回答
  • 面试哥
    面试哥 2021-01-29
    为面试而生,有面试问题,就找面试哥。

    您不清楚确切的失踪日期。我只是假设您要填写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
    

    要填充未观察到的值,我们将使用unstackstack方法。取消堆叠将创建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)中间,以免NaNs掉落。
    stack确实有一个dropna论点。我认为将其设置为false将保留所有NaN行。可能是个错误?



知识点
面圈网VIP题库

面圈网VIP题库全新上线,海量真题题库资源。 90大类考试,超10万份考试真题开放下载啦

去下载看看