When one Pandas datetime column is subtracted from another, the result is a
Timedelta value.
We can divide that duration by a NumPy timedelta64 unit to express the difference as a numeric value in days, weeks, hours, minutes, seconds, milliseconds, microseconds or nanoseconds.
For example:
difference / np.timedelta64(1, 'D')
returns the duration as a number of days.
First, create a DataFrame containing start and end dates.
import pandas as pd
import numpy as np
my_dict={
'NAME':[
'Ravi',
'Raju',
'Alex'
],
'dt_start':[
'1/1/2020',
'2/1/2020',
'5/1/2020'
],
'dt_end':[
'6/15/2022',
'7/22/2022',
'11/15/2023'
]
}
my_data=pd.DataFrame(
data=my_dict
)
my_data['dt_start']=pd.to_datetime(
my_data['dt_start']
)
my_data['dt_end']=pd.to_datetime(
my_data['dt_end']
)
print(my_data)
Output
NAME dt_start dt_end
0 Ravi 2020-01-01 2022-06-15
1 Raju 2020-02-01 2022-07-22
2 Alex 2020-05-01 2023-11-15
The dt_start and dt_end columns are converted to Pandas datetime values using
to_datetime().
Subtract the starting date from the ending date.
my_data['difference']=(
my_data['dt_end']
-
my_data['dt_start']
)
print(my_data)
Output
NAME dt_start dt_end difference
0 Ravi 2020-01-01 2022-06-15 896 days
1 Raju 2020-02-01 2022-07-22 902 days
2 Alex 2020-05-01 2023-11-15 1293 days
The difference column contains Pandas Timedelta values rather than ordinary integers.
Divide the Timedelta by one NumPy day:
my_data['diff_days']=(
my_data['difference']
/
np.timedelta64(
1,
'D'
)
)
print(
my_data[
[
'NAME',
'diff_days'
]
]
)
Output
NAME diff_days
0 Ravi 896.0
1 Raju 902.0
2 Alex 1293.0
The result is numeric, so normal numerical comparisons can now be used.
For example, select records where the date difference is greater than 900 days.
filtered=my_data[
my_data['diff_days'] > 900
]
print(
filtered[
[
'NAME',
'diff_days'
]
]
)
Output
NAME diff_days
1 Raju 902.0
2 Alex 1293.0
Use 'W' to convert the duration to weeks.
my_data['diff_weeks']=(
my_data['difference']
/
np.timedelta64(
1,
'W'
)
)
print(
my_data[
[
'NAME',
'diff_weeks'
]
]
)
Output
NAME diff_weeks
0 Ravi 128.000000
1 Raju 128.857143
2 Alex 184.714286
If only completed whole weeks are required, the result can be converted to integer.
my_data['whole_weeks']=(
my_data['diff_weeks']
.astype(int)
)
print(
my_data[
[
'NAME',
'whole_weeks'
]
]
)
Output
NAME whole_weeks
0 Ravi 128
1 Raju 128
2 Alex 184
Converting a positive floating-point value to integer removes the fractional part.
Use lowercase 'h' for hours.
my_data['diff_hours']=(
my_data['difference']
/
np.timedelta64(
1,
'h'
)
)
print(
my_data[
[
'NAME',
'diff_hours'
]
]
)
Output
NAME diff_hours
0 Ravi 21504.0
1 Raju 21648.0
2 Alex 31032.0
Use 'm' for minutes.
my_data['diff_minutes']=(
my_data['difference']
/
np.timedelta64(
1,
'm'
)
)
print(
my_data[
[
'NAME',
'diff_minutes'
]
]
)
Output
NAME diff_minutes
0 Ravi 1290240.0
1 Raju 1298880.0
2 Alex 1861920.0
Use 's' for seconds.
my_data['diff_seconds']=(
my_data['difference']
/
np.timedelta64(
1,
's'
)
)
print(
my_data[
[
'NAME',
'diff_seconds'
]
]
)
Output
NAME diff_seconds
0 Ravi 77414400.0
1 Raju 77932800.0
2 Alex 111715200.0
Smaller fixed time units can also be used.
my_data['diff_ms']=(
my_data['difference']
/
np.timedelta64(
1,
'ms'
)
)
my_data['diff_us']=(
my_data['difference']
/
np.timedelta64(
1,
'us'
)
)
my_data['diff_ns']=(
my_data['difference']
/
np.timedelta64(
1,
'ns'
)
)
Months and years are different from units such as days or hours because they do not have a fixed duration.
A month can contain 28, 29, 30 or 31 days, and a year can contain 365 or 366 days.
For this reason, current Pandas Timedelta arithmetic does not support dividing a Timedelta by:
np.timedelta64(1, 'M')
np.timedelta64(1, 'Y')
These are ambiguous calendar units rather than fixed durations.
For adding or subtracting calendar components in Pandas, use
DateOffset().
For calendar differences involving years, months and days, see the
relativedelta() tutorial.
If you only need the number of whole days from a Pandas Timedelta Series, Pandas provides a simpler approach through .dt.days.
my_data['days']=(
my_data['difference']
.dt.days
)
print(
my_data[
[
'NAME',
'days'
]
]
)
Output
NAME days
0 Ravi 896
1 Raju 902
2 Alex 1293
This is convenient when only whole days are required.
Using NumPy timedelta64 is useful when the same Timedelta needs to be expressed in several fixed units such as hours, minutes or seconds.
| Unit | Meaning | Example |
|---|---|---|
W |
Week |
np.timedelta64(1, 'W')
|
D |
Day |
np.timedelta64(1, 'D')
|
h |
Hour |
np.timedelta64(1, 'h')
|
m |
Minute |
np.timedelta64(1, 'm')
|
s |
Second |
np.timedelta64(1, 's')
|
ms |
Millisecond |
np.timedelta64(1, 'ms')
|
us |
Microsecond |
np.timedelta64(1, 'us')
|
ns |
Nanosecond |
np.timedelta64(1, 'ns')
|
For Pandas Timedelta division, avoid treating the following as fixed durations:
'M' # calendar month
'Y' # calendar year
For calendar-based months and years, use a calendar-aware approach instead.
np.timedelta64(1, 'D') to get numeric days.'W' for weeks.'h' for hours.'m' for minutes.'s' for seconds.'ms', 'us' and 'ns'..dt.days is a simple way to extract whole days from a Pandas Timedelta Series.np.timedelta64(1, 'M') or np.timedelta64(1, 'Y') for calendar month or year calculations.DateOffset() for adding or subtracting calendar date components.relativedelta() when a calendar difference in years, months and days is required.Author & Instructor at plus2net
I write and maintain practical tutorials on Python, PHP, SQL, JavaScript, HTML, jQuery, and web development at plus2net. The tutorials focus on clear explanations, working examples, and code that readers can test and adapt while learning.