1

If I have a custom list of days like the one below (but it can any arbitrary days):

from datetime import datetime, timedelta

base = datetime.today()
date_list = [base - timedelta(days=x) for x in range(0, 1000)]

How can I extract the first date of each month/year from the list and separately extract the last date of the list?

One way I was thinking of doing this was if I have my list in a pandas.Series then group the dates in their respective month/year and then look at the days of each date and take the lowest (for the first date) and highest day (for the last date).

I just don't know how to do that.

To be clear: I am trying to find the first / last day of the month inside a custom list. For example if I have only 15 Feb 2018 inside my list. This will be both the first and last day of the month for my list.

Newskooler
  • 3,973
  • 7
  • 46
  • 84
  • 1
    Possible duplicate of [Get Last Day of the Month in Python](https://stackoverflow.com/questions/42950/get-last-day-of-the-month-in-python) – Chris Apr 24 '19 at 19:45
  • It's not because I am trying to find the last / first day of the month in a custom list and not generally the first / last day. – Newskooler Apr 24 '19 at 19:46
  • 1
    You should add an example list to make it more clear, else we have to make assumptions. – Erfan Apr 24 '19 at 19:46
  • 1
    Could you add a small sample input and output? I think you mean for any list of dates, pull every first and last day for every month that exists in your list? – MyNameIsCaleb Apr 24 '19 at 19:51
  • That's exactly what I mean. I am trying to add a sample now. – Newskooler Apr 24 '19 at 19:52
  • 1
    You're example does not make it more clear, please read [this](https://stackoverflow.com/questions/20109391/how-to-make-good-reproducible-pandas-examples) to understand how you ask a good `pandas` question. – Erfan Apr 24 '19 at 19:52
  • @ALollz this answers my question. Thank you! – Newskooler Apr 24 '19 at 19:55
  • Sort the dates, iterate through them, and when the month changes from one date to the next, you know those two dates are the first/last days of the month. – John Gordon Apr 24 '19 at 20:04

2 Answers2

3

Create a DataFrame then use resample to aggregate the max and min for each month. normalize gets rid of the time part.

import pandas as pd

(pd.DataFrame(data=pd.to_datetime(date_list).normalize(), index=date_list)
   .resample('MS')[0].agg([min, max]))

#                  min        max
#2016-07-01 2016-07-29 2016-07-31
#2016-08-01 2016-08-01 2016-08-31
#2016-09-01 2016-09-01 2016-09-30
#2016-10-01 2016-10-01 2016-10-31
#2016-11-01 2016-11-01 2016-11-30
#2016-12-01 2016-12-01 2016-12-31
#2017-01-01 2017-01-01 2017-01-31
#2017-02-01 2017-02-01 2017-02-28
#2017-03-01 2017-03-01 2017-03-31
#...
ALollz
  • 57,915
  • 7
  • 66
  • 89
0

I would use grouper and separate the min dates per month and max dates per month.

from datetime import datetime, timedelta

base = datetime.today()
date_list = [base - timedelta(days=x) for x in range(0, 35)]

df = pd.DataFrame(date_list, columns=['date_idx'])
df.index = df['date_idx']
df_min = df.groupby(pd.Grouper(freq='M')).agg(np.min).reset_index(drop=True)
df_max = df.groupby(pd.Grouper(freq='M')).agg(np.max).reset_index(drop=True)

print(df_min)
print(df_max)

Result:

                   date_idx
0 2019-03-21 16:16:58.991884
1 2019-04-01 16:16:58.991884

                    date_idx
0 2019-03-31 16:16:58.991884
1 2019-04-24 16:16:58.991884
jose_bacoy
  • 12,227
  • 1
  • 20
  • 38