我如何融化数据框以获取范围内的所有日期?

时间:2019-05-27 17:16:02

标签: python pandas

我有一个像这样的数据集:

    import pandas as pd    
    pd.DataFrame({'col1': [1, 2], 'start date': ['1/3/2019', '1/10/2019'],
                                  'end date':['1/5/2019','1/12/2019']} )

我想为开始日期和结束日期之间的每个值获取一行。

    pd.DataFrame({'col1': [1,1,1,2,2,2],
                  'date': ['1/3/2019','1/4/2019','1/5/2019',
                           '1/10/2019', '1/11/2019', '1/12/2019'],

                  'start date': ['1/3/2019', '1/3/2019', '1/3/2019',
                           '1/10/2019', '1/10/2019', '1/10/2019'],

                  'end date':['1/5/2019','1/5/2019','1/5/2019',
                           '1/12/2019','1/12/2019','1/12/2019']} )

编辑:允许范围重叠。

我正在尝试使用melt,但我无法获得想要的东西。

3 个答案:

答案 0 :(得分:1)

这里需要考虑使用pd.date_rangegroupby.apply的东西:

df = pd.DataFrame({'col1': [1, 2], 'start date': ['1/3/2019', '1/10/2019'], 'end date':['1/5/2019','1/12/2019']} )
df.set_index(['col1', 'start date', 'end date'], inplace=True)
df_result = df.groupby(['col1', 'start date', 'end date']).apply(lambda df_: pd.date_range(*df_.index[0][1:], freq='D').to_frame(index=True, name='date'))
df_result.reset_index(inplace=True)
df_result.reindex(['col1', 'date', 'start date', 'end date'], axis=1)

# produces the following:

   col1       date start date   end date
0     1 2019-01-03   1/3/2019   1/5/2019
1     1 2019-01-04   1/3/2019   1/5/2019
2     1 2019-01-05   1/3/2019   1/5/2019
3     2 2019-01-10  1/10/2019  1/12/2019
4     2 2019-01-11  1/10/2019  1/12/2019
5     2 2019-01-12  1/10/2019  1/12/2019

答案 1 :(得分:1)

我将使用range_index来构建开始日期和结束日期之间的日期列表,从每一行中构建一个部分数据框,然后将它们全部连接起来:

pd.concat(
    [pd.DataFrame(row.to_dict(), index = pd.date_range(
        start = pd.to_datetime(df.loc[i, 'start date']),
        end = pd.to_datetime(df.loc[i, 'end date']),
        freq = 'D')).rename_axis('date').reset_index()
     for i, row in df.iterrows()], ignore_index=True)

答案 2 :(得分:1)

我将apply与自定义函数一起使用,从pd.date_range返回一系列序列

def create_range(x):
    s = pd.Series(pd.date_range(start=x['start date'], end=x['end date'])).dt.strftime('%m/%d/%Y')
    return s

applystackreset_index上使用上面的自定义函数并与df联接

df[['start date', 'end date']].apply(create_range, axis=1).stack().reset_index(level=-1, drop=True).to_frame('date').join(df)


Out[1742]:
         date  col1   end date start date
0  01/03/2019     1   1/5/2019   1/3/2019
0  01/04/2019     1   1/5/2019   1/3/2019
0  01/05/2019     1   1/5/2019   1/3/2019
1  01/10/2019     2  1/12/2019  1/10/2019
1  01/11/2019     2  1/12/2019  1/10/2019
1  01/12/2019     2  1/12/2019  1/10/2019