查找两个日期列之间的所有月份并为每个月份生成行

问题描述 投票:4回答:3

我有一个包含两个日期列的数据框:

   Date1       Date2
2018-10-02    2018-12-21
2019-01-20    2019-04-30

依此类推

我想创建第三列,基本上是包含两个日期之间所有月份的列,如下所示:

   Date1       Date2           months
2018-10-02    2018-12-21       201810
2018-10-02    2018-12-21       201811
2018-10-02    2018-12-21       201812
2019-01-20    2019-04-30       201901
2019-01-20    2019-04-30       201902
2019-01-20    2019-04-30       201903
2019-01-20    2019-04-30       201904

我该怎么做?我尝试使用此公式:

df['months']=df.apply(lambda x: pd.date_range(x.Date1,x.Date2, freq='MS').strftime("%Y%m"))

但是我没有得到想要的结果。请帮助。谢谢

python pandas numpy date
3个回答
5
投票

使用merge

final = df.merge(df.apply(lambda s: pd.date_range(s.Date1, s.Date2, freq='30D'), 1)\
                   .explode()\
                   .rename('Months')\
                   .dt.strftime('%Y%m'),
                 left_index=True, 
                 right_index=True)

   Months       Date1       Date2
0  201810  2018-10-02  2018-12-21
0  201811  2018-10-02  2018-12-21
0  201812  2018-10-02  2018-12-21
1  201901  2019-01-20  2019-04-30
1  201902  2019-01-20  2019-04-30
1  201903  2019-01-20  2019-04-30
1  201904  2019-01-20  2019-04-30

2
投票

groupbypd.date_rangejoin一起使用。

通知:我使用了replace(day=1),以确保我们每个月都能抓到。

months = df.groupby(level=0).apply(lambda x: pd.date_range(x['Date1'].iat[0].replace(day=1), 
                                                           x['Date2'].iat[0], 
                                                           freq='MS')).explode().to_frame(name='Months')

df2 = months.join(df).reset_index(drop=True)

输出

      Months      Date1      Date2
0 2018-10-01 2018-10-02 2018-12-21
1 2018-11-01 2018-10-02 2018-12-21
2 2018-12-01 2018-10-02 2018-12-21
3 2019-01-01 2019-01-20 2019-04-30
4 2019-02-01 2019-01-20 2019-04-30
5 2019-03-01 2019-01-20 2019-04-30
6 2019-04-01 2019-01-20 2019-04-30

1
投票

您可以融合数据,重新采样并合并回去:

df.merge(df.reset_index()                               # reset index as column
           .melt(id_vars='index', value_name='months')  # usual melt
           .resample('M', on='months')                  # resample to get the month list
           .first().ffill()                             # interpolate the index
           .drop(['variable', 'months'], axis=1)        # remove unnecessary columns
           .reset_index(),                              # make months a column
         left_index=True,
         right_on='index'
)

输出:

       Date1      Date2     months  index
0 2018-10-02 2018-12-21 2018-10-31    0.0
1 2018-10-02 2018-12-21 2018-11-30    0.0
2 2018-10-02 2018-12-21 2018-12-31    0.0
3 2019-01-20 2019-04-30 2019-01-31    1.0
4 2019-01-20 2019-04-30 2019-02-28    1.0
5 2019-01-20 2019-04-30 2019-03-31    1.0
6 2019-01-20 2019-04-30 2019-04-30    1.0
© www.soinside.com 2019 - 2024. All rights reserved.