Reputation: 1661
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.
Upvotes: 84
Views: 117172
Reputation: 2925
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]
Upvotes: 3
Reputation: 2836
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')]
Upvotes: 48
Reputation: 682
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))
Upvotes: 10
Reputation: 35
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.
Upvotes: 2
Reputation: 425
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`
Upvotes: 2
Reputation: 29916
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.
Upvotes: 154
Reputation: 134
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)
Upvotes: 6
Reputation: 880
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.
Upvotes: 3
Reputation: 8576
def nearestDate(base, dates):
nearness = { abs(base.timestamp() - date.timestamp()) : date for date in dates }
return nearness[min(nearness.keys())]
Upvotes: 1