Найти ближайшую дату в списке дат - PullRequest
2 голосов
/ 07 февраля 2020

Я пытаюсь найти ближайшую дату в списке дат на текущую дату. Я нашел несколько примеров поиска ближайшей даты в списке, но все они позволяют возвращать дополнительную дату.

Список даты и времени имеет следующую форму:

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

До сих пор я реализовывал следующую функцию, чтобы найти ближайшую дату;

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)

Но это возвращает дату, ближайшую к текущей, половину времени, когда возвращается самая близкая дата в будущее. Я также пытался реализовать функцию numpy searchsorted, но, похоже, она всегда возвращает ближайшую будущую дату, независимо от того, выбираю ли я «right» или «left» для параметра side, следующими способами:

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

Функция поиска с сортировкой numpy возвращает (если бы я должен был выполнить это сегодня, 7 февраля 2020 г.) 4 (что соответствует datetime.datetime (2020, 2, 10, 0, 0)) в любом случае. Кто-нибудь знает способ гарантировать, что самая близкая дата в прошлом всегда возвращается?

Ответы [ 2 ]

3 голосов
/ 07 февраля 2020

Использование min с двумя key с будет одним из способов:

from datetime import datetime

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

Вывод:

datetime.datetime(2020, 1, 31, 0, 0)
1 голос
/ 07 февраля 2020

Вы можете использовать np.searchsorted, как вы уже пытались с его side аргументом, установленным как right, так что он рассматривает только те, что перед ним или такие же, как он сам. Теперь, так как по определению searchsorted получает индекс позиции для поиска в большем отсортированном массиве, нам нужно вычесть 1, чтобы получить ближайшую перед ним.

Следовательно, просто сделайте -

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

Образцы прогонов -

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)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...