使用 pandas.Grouper 将 datetime.time 列拆分为时间范围

Using pandas.Grouper to split datetime.time column into time ranges

我正在读取一个 Excel 文件,其中有一列包含时间。由于我无法上传实际文件,因此我创建了变量 timeIntervals 来说明。

当我运行这段代码...

import pandas as pd
import datetime
from pyPython import *

def main():
    timeIntervals = pd.date_range("11:00", "21:30", freq="30min").time
    df = pd.DataFrame({"Times": timeIntervals})
    grp = pd.Grouper(key="Times", freq="3H")
    value = df.groupby(grp).count()
    print(value)

if __name__ == '__main__':
    main()

我收到以下错误:

TypeError: Only valid with DatetimeIndex, TimedeltaIndex or PeriodIndex, but got an instance of 'Index'

如何将 pandas.GrouperDataFrame.groupby 结合使用以将数据帧 df“分组”到离散时间范围(3 小时)?还有其他选择吗?

几个问题:

  1. A date_range 不能仅减少到 time 而不会丢失按时重新采样所需的数据类型 window.
  2. count 计算一列中的非 NaN 值,因此必须提供一个,因为样本框中没有剩余的列。

我们可以通过将时间列转换为日期时间来解决第一个问题:

timeIntervals = pd.date_range("11:00", "21:30", freq="30min") # remove time here
df = pd.DataFrame({"Times": timeIntervals})

如果我们不是从 date_range 创建这些值,我们可以简单地转换列 to_datetime:

df['Times'] = pd.to_datetime(df['Times'], format='%H:%M:%S')

然后我们可以groupby并计数:

value = df.groupby(pd.Grouper(key="Times", freq="3H"))['Times'].count()

如果需要,我们可以更新 index 以仅反映分组后的 time

value.index = value.index.time

因此 value 变为:

09:00:00    2
12:00:00    6
15:00:00    6
18:00:00    6
21:00:00    2
Name: Times, dtype: int64

全部加上to_datetime:

def main():
    time_intervals = pd.date_range("11:00", "21:30", freq="30min").time
    df = pd.DataFrame({"Times": time_intervals})
    # Convert to DateTime
    df['Times'] = pd.to_datetime(df['Times'], format='%H:%M:%S')
    # Group and count specific column
    value = df.groupby(pd.Grouper(key="Times", freq="3H"))['Times'].count()
    # Retrieve only Time information
    value.index = value.index.time
    print(value)

或者在创建 DataFrame 之前不检索 time

def main():
    time_intervals = pd.date_range("11:00", "21:30", freq="30min")
    df = pd.DataFrame({"Times": time_intervals})
    value = df.groupby(pd.Grouper(key="Times", freq="3H"))['Times'].count()
    value.index = value.index.time
    print(value)