Панды как фильтровать фрейм данных по периоду времени


У меня есть файл с нижеприведенной таблицей:

    Name        AvailableDate            totalRemaining
0   X3321       2018-03-14 13:00:00      200
1   X3321       2018-03-14 14:00:00      200
2   X3321       2018-03-14 15:00:00      200
3   X3321       2018-03-14 16:00:00      200
4   X3321       2018-03-14 17:00:00      193

Я хотел вернуть фрейм данных со всеми записями в определенный период времени независимо от фактической даты.

Я последовал примеру здесь:

Фильтровать фрейм данных pandas по времени

Но когда я выполняю следующее:

## setup
import pandas as pd
import numpy as np

### Step 2
### Check available slots
file2 = r'C:UsersuserDesktopFilesdata.xlsx'

slots = pd.read_excel(file2,na_values='')

## filter the preffered ones
slots['nextAvailableDate'] = pd.to_datetime((slots['nextAvailableDate']))


slots['times'] = pd.to_datetime((slots['nextAvailableDate']))
slots = slots[slots['times'].between('21:00:00', '02:00:00')]

Это возвращает пустой фрейм данных, а также это решение:

slots = slots[slots['times'].dt.strftime('%H:%M:%S').between('21:00:00', '02:00:00')]

Есть ли способ сделать это правильно, не создавая столбцы для времени по отдельности? Как я должен подойти к этой проблеме, пожалуйста?

Моя цель:

Name        AvailableDate            totalRemaining
0   X3321       2018-03-14 21:00:00      200
1   X3321       2018-03-14 22:00:00      200
2   X3321       2018-03-14 23:00:00      200
3   X3321       2018-03-14 00:00:00      200
4   X3321       2018-03-14 01:00:00      193

Для каждого дня, который появляется в наборе данных.

2 2

2 ответа:

Я думаю, нужно between_time работа с Datetimeindex, созданным set_index, для столбцов добавить reset_index с помощью reindex для того же порядка столбцов:

print (slots)
     Name        AvailableDate  totalRemaining
0   X3321  2018-03-14 21:00:00             200
1   X3321  2018-03-14 20:00:00             200
2   X3321  2018-03-14 22:00:00             200
3   X3321  2018-03-14 23:00:00             200
4   X3321  2018-03-14 00:00:00             200
5   X3321  2018-03-14 01:00:00             193
6   X3321  2018-03-14 13:00:00             200
7   X3321  2018-03-14 14:00:00             200
8   X3321  2018-03-14 15:00:00             200
9   X3321  2018-03-14 16:00:00             200
10  X3321  2018-03-14 17:00:00             193

slots['AvailableDate'] = pd.to_datetime(slots['AvailableDate'])

df = (slots.set_index('AvailableDate')
          .between_time('21:00:00', '02:00:00')
          .reset_index()
          .reindex(columns=df.columns))
print (df)
        AvailableDate   Name  totalRemaining
0 2018-03-14 21:00:00  X3321             200
1 2018-03-14 22:00:00  X3321             200
2 2018-03-14 23:00:00  X3321             200
3 2018-03-14 00:00:00  X3321             200
4 2018-03-14 01:00:00  X3321             193

Вы можете использовать pd.Series.between с datetime объектами, как показано ниже.

from datetime import datetime

start = datetime.strptime('21:00:00', '%H:%M:%S').time()
end = datetime.strptime('02:00:00', '%H:%M:%S').time()

slots = slots[slots['times'].dt.time.between(start, end)]

Пример использования

from datetime import datetime
import pandas as pd

slots = pd.DataFrame({'times': ['2018-03-08 05:00:00', '2018-03-08 07:00:00',
                                '2018-03-08 01:00:00', '2018-03-08 20:00:00',
                                '2018-03-08 22:00:00', '2018-03-08 23:00:00']})

start = datetime.strptime('21:00:00', '%H:%M:%S').time()
end = datetime.strptime('23:30:00', '%H:%M:%S').time()

slots = slots[slots['times'].dt.time.between(start, end)]

#                 times
# 4 2018-03-08 22:00:00
# 5 2018-03-08 23:00:00