python - 按工作日和时间更好地选择 Pandas DatetimeIndex

标签 python pandas

问题:按工作日和时间从 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。)

Pivoted final output for code validation

最佳答案

看来您可以使用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')

现在我看到的输出如下所示: enter image description here

关于python - 按工作日和时间更好地选择 Pandas DatetimeIndex,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58532111/

相关文章:

python - 从一天的开始按 n 天对 Pandas DataFrame 进行分组

python - 如何在Python中将简单列表转换为数据框

python - 无法解开从 pandas DataFrame 继承的类

python - JSON到 Pandas 数据框

python - 无法在 REST API 的 flask 中返回 json 分页

python - 模块未找到错误: No module named 'tensorflow' ?

python - 在 Python 中处理 HTTP IncompleteRead 错误

python - Pandas 数据框 : Split multiple columns each into two columns

Windows 7 的 AndroidViewClient 安装

python - 异征 : Problems with indentation