问题:按工作日和时间从 Pandas DatetimeIndex
中进行选择。例如,我想选择星期二 20:00 到星期五 06:00 之间的所有项目。
问题:是否有比我下面的解决方案更好的解决方案?
我有一个现有的解决方案(见下文),但由于以下原因我不太喜欢它:
- 它将时间戳转换为 float 并进行 float 比较,但存在常见的准确性问题。
- 通过针对手头任务的人为映射从丰富数据类型转换为原始数据类型似乎既不优雅也不Pythonic。
- 周日(第 6 周)至周一(第 0 周)的选择需要 klugdy 特殊处理(不属于下面示例的一部分)。
我的工作示例:
import pandas as pd
from datetime import time
import calendar
# The DatetimeIndex to selection from
idx = pd.date_range('2019-01-01', '2019-01-31', freq='H')
# Converts a datetime to a time-of-day fraction in [0, 1)
def datetime_to_time_frac(t):
return t.hour / 24 + t.minute / (24 * 60) + t.second / (24 * 60 * 60)
# Converts a datetime to a float representing weekday (Monday: 0 to Sunday: 6) + time-of-day fraction in [0, 1)
def datetime_to_weekday_time_frac(t):
return t.weekday + datetime_to_time_frac(t)
# DatetimeIndex converted to float
idx_conv = datetime_to_weekday_time_frac(idx)
# Boolean mask selecting items between Tuesday 20:00 and Friday 06:00
mask = (idx_conv >= calendar.TUESDAY + datetime_to_time_frac(time(20, 0)))\
& (idx_conv <= calendar.FRIDAY + datetime_to_time_frac(time(6, 0)))
# Validation of mask in a pivot table
df = pd.DataFrame(index=idx[mask])
df['Date'] = df.index.date
df['Weekday'] = df.index.weekday
weekdays = list(calendar.day_abbr)
df['WeekdayName'] = df.Weekday.map(lambda x: weekdays[x])
df['Hour'] = df.index.hour
df.pivot_table(index=['Date', 'WeekdayName'], columns='Hour', values='Weekday', aggfunc='count')
最终的旋转输出表明代码做了正确的事情,但我有一种感觉,有一种更优雅和惯用的方法来解决这个问题。
(代码基于 Python 3 和最新的 Pandas。)
最佳答案
看来您可以使用pandas
中的内部索引功能来更干净地索引它。我正在避免转换为分数时间,并且不可否认,我所做的事情只适用于整个小时。基本区别是使用 pandas 内置功能并避免将 calendars
作为导入。这是我所做的,基本上与您周二至周五的具体示例相同,但如果您只需要每小时的间隔,您可以将其调整为更一般的情况。
import pandas as pd
idx = pd.date_range('2019-01-01', '2019-01-31', freq='H')
df = pd.DataFrame(index=idx)
# Build a series of filters for each part of your weekly interval.
tues = (df.index.weekday == 1) & (df.index.hour >= 6)
weds_thurs = df.index.weekday.isin([2,3])
fri = (df.index.weekday == 4) & (df.index.hour <= 20)
# The mask is just the union of all those conditions
mask = tues | weds_thurs | fri
# now apply the mask and the rest is basically what you were doing
df = df.loc[mask]
df['Date'] = df.index.date
df['Weekday'] = df.index.weekday
df['WeekdayName'] = df.index.weekday_name
df['Hour'] = df.index.hour
df.pivot_table(index=['Date', 'WeekdayName'], columns='Hour', values='Weekday', aggfunc='count')
关于python - 按工作日和时间更好地选择 Pandas DatetimeIndex,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58532111/