我有一个像这样的数据集:
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
,但我无法获得想要的东西。
答案 0 :(得分:1)
这里需要考虑使用pd.date_range
和groupby.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
在apply
,stack
,reset_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