在多索引数据框中添加缺失日期索引

时间:2020-06-17 19:56:33

标签: python pandas dataframe

我正在使用以日期列和location_id作为索引的多索引数据框。

index_1 = ['2020-01-01', '2020-01-03', '2020-01-04']
index_2 = [100,200,300]

index = pd.MultiIndex.from_product([index_1, 
index_2], names=['Date', 'location_id'])

df = pd.DataFrame(np.random.randint(10,100,9), index)
df

                         0
Date       location_id    
2020-01-01 100          19
           200          75
           300          39
2020-01-03 100          11
           200          91
           300          80
2020-01-04 100          36
           200          56
           300          54

我想用一个location_id填写缺少的日期,并用0填充它:

                         0
Date       location_id    
2020-01-01 100          19
           200          75
           300          39
2020-01-02 100          0
2020-01-03 100          11
           200          91
           300          80
2020-01-04 100          36
           200          56
           300          54

我该如何实现? This is helpful,但前提是我的数据框未进行多索引。

3 个答案:

答案 0 :(得分:3)

熊猫索引是不可变的,因此您需要构建一个新索引。将索引级别location_id放入列中并获得唯一的行,然后调用asfreq创建缺少日期的行。将结果分配给df2。最后,使用df.align连接两个索引和fillna

df1 = df.reset_index(-1)
df2 = df1.loc[~df1.index.duplicated()].asfreq('D').ffill()
df_final = df.align(df2.set_index('location_id', append=True))[0].fillna(0)

Out[75]:
                           0
Date       location_id
2020-01-01 100          19.0
           200          75.0
           300          39.0
2020-01-02 100           0.0
2020-01-03 100          11.0
           200          91.0
           300          80.0
2020-01-04 100          36.0
           200          56.0
           300          54.0

答案 1 :(得分:2)

您可以获取日期索引级别的unique值,并使用pd.date_range生成介于最小值和最大值之间的所有日期,并使用具有唯一值Date的difference来获取缺失的日期。然后,将reindex df与原始索引的union和由遗漏日期组成的MultiIndex.from_product和级别location_id的min组成。

#unique dates
m = df.index.unique(level=0)
# reindex
df = df.reindex(df.index.union(
                   pd.MultiIndex.from_product([pd.date_range(m.min(), m.max())
                                                .difference(pd.to_datetime(m))
                                                .strftime('%Y-%m-%d'), 
                                             [df.index.get_level_values(1).min()]])), 
                fill_value=0)
print(df)
                 0
2020-01-01 100  91
           200  49
           300  19
2020-01-02 100   0
2020-01-03 100  41
           200  25
           300  51
2020-01-04 100  44
           200  40
           300  54

您也可以使用pd.MultiIndex.from_product中的product代替itertools。结果相同,但可能更快。

from itertools import product
df = df.reindex(df.index.union(
                  list(product(pd.date_range(m.min(), m.max())
                                 .difference(pd.to_datetime(m))
                                 .strftime('%Y-%m-%d'),
                               [df.index.get_level_values(1).min()]))),
                fill_value=0)

答案 2 :(得分:0)

request.userpassports.authenticate可以工作:

unstack/stack

输出:

asfreq/reindex