Расчет даты и времени в зависимости от списка дат - PullRequest
0 голосов
/ 19 января 2019

Доброе утро.

Моя проблема заключается в следующем: у меня есть файл данных pandas со столбцом с именем 'fecha', в котором хранятся объекты даты, и список кортежей, в котором хранятся начальное и конечное время. Показать примеры ниже:

df = 
     fecha
0    2018-10-01
1    2019-01-12
2    2018-12-25

list_ranges = [(datetime.datetime(2018, 10, 1, 0, 0), 
datetime.datetime(2018, 10, 15, 0, 0)),
(datetime.datetime(2018, 10, 16, 0, 0),
datetime.datetime(2018, 10, 31, 0, 0)),
(datetime.datetime(2018, 11, 1, 0, 0), datetime.datetime(2018, 11, 15, 0, 0)),
(datetime.datetime(2018, 11, 16, 0, 0),
datetime.datetime(2018, 11, 30, 0, 0)),
(datetime.datetime(2018, 12, 1, 0, 0), datetime.datetime(2018, 12, 15, 0, 0)),
(datetime.datetime(2018, 12, 16, 0, 0),
datetime.datetime(2018, 12, 31, 0, 0)),
(datetime.datetime(2019, 1, 1, 0, 0), datetime.datetime(2019, 1, 15, 0, 0))] 

и я хочу получить позицию диапазона, в котором каждая дата находится в списке. Результат, который я ищу:

df = 
     result
0    1
1    7
2    6

В настоящее время я делаю это:

df.fecha = df.fecha.apply(lambda x: select_quincena(x, quincenas))

def select_quincena(fecha, quincenas):

    fecha = datetime.datetime.combine(fecha, datetime.datetime.min.time())
    num   = 0

    for e in quincenas:
        num += 1

        if fecha >= e[0] and fecha <= e[1]:

            return num

Работает нормально, но я уверен, что есть лучший и более простой способ сделать это.

Заранее большое спасибо.

1 Ответ

0 голосов
/ 19 января 2019

Использование pd.to_datetime, не модуль datetime

Сначала конвертируйте вашу серию в Панд datetime:

df['fecha'] = pd.to_datetime(df['fecha'])

Используйте pd.cut для хранения категорий

Это проблема биннинга. Вы можете использовать pd.cut для векторизованного решения:

import numpy as np
from operator import itemgetter

dates = pd.to_datetime([list_ranges[0][0], *map(itemgetter(1), list_ranges)]).values
labels = np.arange(1, len(dates))

df['result'] = pd.cut(df['fecha'].values, bins=dates, labels=labels, include_lowest=True)

print(df)

       fecha result
0 2018-10-01      1
1 2019-01-12      7
2 2018-12-25      6

Related: Фильтрация и создание столбца на основе столбца даты

Используйте np.searchsorted для целочисленных меток

Также возможен в этом случае бинарный поиск для поиска требуемых точек вставки. Это эффективно реализовано в np.searchsorted.

df['result'] = np.searchsorted(dates, df['fecha'].values, side='right')

Обработка ошибок Cannot cast array data

Выше тестируется для работы на Pandas 0.23.4 / NumPy 1.15.1. Для других версий сравнение типов может быть непоследовательным. В этом случае вы можете конвертировать datetime массивы в целые числа, заменяя каждое извлечение .values на .values.astype('datetime64[D]').astype(int).

Related: Невозможно привести данные массива из dtype ('M8-ns') к dtype ('float64') в соответствии с правилом 'safe' .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...