In this guide, we will see how to extract day, night, morning, afternoon, evening from Pandas DataFrame.

We would like to map and return information about part of the day from datetime or string column in DataFrame.

Below you can find short answer:

(1) Get Day or Night from datetime

mask = (pd.to_timedelta(df['time']).between(pd.Timedelta('6h'),pd.Timedelta('18h')))
df['new'] = np.where(mask, 'Day', 'Night')

(2) Get morning, noon, evening

df['day_part'] = (pd.to_datetime(df["date"]).dt.hour % 24 + 4) // 4
mapping = {1: 'Late Night', 2: 'Early Morning', 3: 'Morning',
                      4: 'Noon', 5: 'Evening', 6: 'Night'}

df['day_part'].replace(mapping)

Setup

Suppose that we have a dataset which contains the following values with date and time information:

import pandas as pd
dict = {'date': {0: '28-01-2022  5:25:00 PM',
  1: '27-02-2022  6:25:00 PM',
  2: '30-03-2022  7:25:00 PM',
  3: '29-04-2022  8:25:00 PM',
  4: '31-05-2022  9:25:00 PM'},
 'time': {0: '5:25:00', 1: '6:25:00', 2: '7:25:00', 3: '8:25:00', 4: '9:25:00'}}

df = pd.DataFrame(dict)

data:

date time
0 28-01-2022 5:25:00 PM 5:25:00
1 27-02-2022 6:25:00 PM 6:25:00
2 30-03-2022 7:25:00 PM 7:25:00
3 29-04-2022 8:25:00 PM 8:25:00
4 31-05-2022 9:25:00 PM 9:25:00

Let's check how to extract part of the day from this DataFrame.

If you have datetime stored as a string you can convert to to datetime by:

df["date"] = pd.to_datetime(df["date"]).

Step 1: Extract day or night

If we like to extract day or night we can use pd.to_timedelta() to calculate the difference of the hours. Then we can map as follows:

  • 6 - 18 - Day
  • 0 - 6; 18 - 0 - Night
mask = (pd.to_timedelta(df['time']).between(pd.Timedelta('6h'),pd.Timedelta('18h')))
df['day_night'] = np.where(mask, 'Day', 'Night')
df['day_night']

So the result is:

0    Night
1      Day
2      Day
3      Day
4      Day
Name: day_night, dtype: object

How does it work?

First we calculate the timedelta by:

pd.to_timedelta(df['time'])

which give us:

0   0 days 05:25:00
1   0 days 06:25:00
2   0 days 07:25:00
3   0 days 08:25:00
4   0 days 09:25:00
Name: time, dtype: timedelta64[ns]

Then use .between() to find if it is between 6 or 18 hours. Finally we use the mask to map day and night.

Step 2: Extract morning, noon, evening or night

What if we need to extract more parts of daytime like:

  • early morning
  • morning
  • noon
  • evening
  • night
  • late night

If we divide the day night cycle into 6 equal parts we can do:

df['day_part'] = (pd.to_datetime(df["date"]).dt.hour % 24 + 4) // 4
mapping = {1: 'Late Night', 2: 'Early Morning', 3: 'Morning',
                      4: 'Noon', 5: 'Evening', 6: 'Night'}

df['day_part'].replace(mapping)

This would give use:

0    Evening
1    Evening
2    Evening
3      Night
4      Night
Name: day_part, dtype: object

This solution is taken from: Get part of day (morning, afternoon, evening, night) in Python dataframe

Step 3: Custom mapping of day parts

What if we need to use custom mapping - for example different number of day parts or duration. Then we can build function and apply it to Pandas column as follows:

def get_part_of_day(h):
    if type(h) == int:
        return (
            "morning"
            if 5 <= h <= 11
            else "afternoon"
            if 12 <= h <= 17
            else "evening"
            if 18 <= h <= 22
            else "night"
        )
    else:
        'error'

df['h'] = pd.to_datetime(df["date"]).dt.hour
df['h'].apply(get_part_of_day)

First we get the hour for each record. Then we map result to:

  • 5 - 11 is morning
  • 12 - 17 - afternoon
  • 18 - 22 - evening
  • all the rest is night

This mapping is taken from: part_of_day.py

Conclusion

This post gave several solutions on how to extract day or night, morning, noon or evening.

We saw how to use custom mapping to day parts or a generic mapping. We saw how to map date and time in Python and Pandas to different day periods.