Find the closest date to a given date

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.

92644 次浏览
def nearestDate(base, dates):
nearness = { abs(base.timestamp() - date.timestamp()) : date for date in dates }
return nearness[min(nearness.keys())]

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.

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')]

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.

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)

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))

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`

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.

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]