简体   繁体   中英

Find closest past date in list of dates

I'm trying to find the closest past date in a list of dates to the current date. I've found several examples of searching for the closest date in a list but all these allow for the option of a further date to be returned.

The list of datetimes has the following form:

datelist =
[datetime.datetime(2019, 12, 31, 0, 0),
 datetime.datetime(2020, 1, 10, 0, 0),
 datetime.datetime(2020, 1, 20, 0, 0),
 datetime.datetime(2020, 1, 31, 0, 0),
 datetime.datetime(2020, 2, 10, 0, 0),
 datetime.datetime(2020, 2, 20, 0, 0)]

Up until now I have been implementing the following function to find the closest date;

def nearest_ind(items, pivot):
    '''
    Find the nearest value to the given value (the pivot) in a list.
    '''
    time_diff = np.abs([date - pivot for date in items])
    return time_diff.argmin(0)

But this returns the closest date to the current date, half of the time this returns the closest date in the future. I've also been looking at implementing numpy searchsorted function, but this seems to always return the closest future date, regardless of whether I select "right" or "left" for the side parameter, in the following ways:

np.searchsorted(datelist, datetime.datetime.now(), side='right')
np.searchsorted(datelist, datetime.datetime.now(), side='left')

The numpy searchsorted function returns (if I was to run this today, 7th February 2020) 4 (corresponding to datetime.datetime(2020, 2, 10, 0, 0)) in either instance. Does anyone know of a way to ensure the closest date in the past is always returned?

Using min with two key s would be one way:

from datetime import datetime

now = datetime.now()
min(datelist, key=lambda x: (x>now, abs(x-now)) )

Output:

datetime.datetime(2020, 1, 31, 0, 0)

You can use np.searchsorted as you already attempted with its side arg set as right , so that it considers only the ones before it or same as itself. Now, since by its definition searchsorted gets us the index of position of the date to be searched in the larger sorted array, we need to subtract 1 to get the closest one before it.

Hence, simply do -

datelist[np.searchsorted(datelist, datetime.datetime.now(), side='right')-1]

Sample runs -

In [48]: datelist = [datetime.datetime(2020, 2, 5, 0, 0),
    ...:  datetime.datetime(2020, 2, 8, 0, 0),
    ...:  datetime.datetime(2020, 2, 12, 0, 0),
    ...:  datetime.datetime(2020, 2, 20, 0, 0)]

In [49]: datelist[np.searchsorted(datelist, datetime.datetime(2020, 2, 11, 0, 0), side='right')-1]
Out[49]: datetime.datetime(2020, 2, 8, 0, 0)

In [50]: datelist[np.searchsorted(datelist, datetime.datetime(2020, 2, 7, 0, 0), side='right')-1]
Out[50]: datetime.datetime(2020, 2, 5, 0, 0)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM