Find the closest date to a given date

Question:

I have an array of datetime objects, and I would like to find which element in the array is the closest to a given date (e.g datetime.datetime(2014,12,16))

This post shows how to find the nearest date which is not before the given date. How can I alter this code so that it can return dates that are before a given date?

For example, if the array housed elements datetime.datetime(2014,12,10) and datetime.datetime(2014,12,28), the former item should be returned because it is closest to datetime.datetime(2014,12,16) in absolute value.

Asked By: user3600497

||

Answers:

def nearestDate(base, dates):
    nearness = { abs(base.timestamp() - date.timestamp()) : date for date in dates }
    return nearness[min(nearness.keys())]
Answered By: 3442

This function will return the datetime in items which is the closest to the date pivot.

def nearest(items, pivot):
    return min(items, key=lambda x: abs(x - pivot))

The good part this function works on types other than datetime too out of the box, if the type supports comparison, subtraction and abs, e.g.: numbers and vector types.

Answered By: Tamas Hegedus

As answered on this link link, ‘truncate’ function is there for you.

df.truncate(before='2012-01-07')

Or you can use get_loc with ‘nearest’, ‘backfill’ or ‘ffill’ option.

df.iloc[df.index.get_loc(datetime.datetime(2016,2,2),method='nearest')]
Answered By: Kevin Zhu

To find a closest date and return the timedelta (difference between two dates) I did the following:

def nearest_date(items,pivot):
    nearest=min(items, key=lambda x: abs(x - pivot))
    timedelta = abs(nearest - pivot)
    return nearest, timedelta

This may be useful when you have a minimum threshold for nearness for your app like I did.

Answered By: MarMat

My solution to find the closest index instead of the value

def nearest_ind(items, pivot):
    time_diff = np.abs([date - pivot for date in items])
    return time_diff.argmin(0)
Answered By: Lorenzo Meneghetti

This code returns the nearest date before the given date:

def nearest(items, pivot):
    return min([i for i in items if i <= pivot], key=lambda x: abs(x - pivot))
Answered By: Chiel

Assuming you want to answer the slight variant:
“Given a dataframe with a datetime index, how do I determine the last value of column col where “last” is defined as the last index that is less than some value date


def last(df, date, col):
    return df.loc[                      # access the dataframe using this index
        max(                            # latest date
            df[df.index < date].index   # that precedes `date`
        )
    ][col]                              # access column `col`
Answered By: Tim P

I know this is an old answer, but I just used the code code that Tamas posted and found that it was taking quite a long time – I optimised it and saw much quicker performance; the problem was the iteration was taking a long time, this is my new method – it will only be quicker when the actual pivot appears in the list

def nearest(items, pivot):
    if pivot in items:
    return pivot
else:
    return min(items, key=lambda x: abs(x - pivot))

Hope this helps anyone who came accross this question.

Answered By: Wes

Using numpy is about 2X faster than loop/lambda approaches. all_dates below is a numpy array of dates.

abs_deltas_from_target_date = np.absolute(all_dates - target_date_raw)
index_of_min_delta_from_target_date = np.argmin(abs_deltas_from_target_date)
closest_date = all_dates[index_of_min_delta_from_target_date]
Answered By: Ron Cohen
Categories: questions Tags: , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.