【问题标题】:Using pandas.Grouper to split datetime.time column into time ranges使用 pandas.Grouper 将 datetime.time 列拆分为时间范围
【发布时间】:2021-12-12 07:08:41
【问题描述】:

我正在读取包含时间列的 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 小时)?还有其他选择吗?

【问题讨论】:

  • 在分组前执行df['Times'] = pd.to_timedelta(df['Times'])。为什么你需要使用datetime.time 而不是pd.Timedelta
  • 谢谢@Quang Hoang。我正在阅读一个包含时间列的 Excel 文件。您是否建议另一种方法?

标签: python pandas dataframe datetime pandas-groupby


【解决方案1】:

几个问题:

  1. date_range 不能仅简化为 time,而不会丢失按时间窗口重新采样所需的数据类型。
  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和count了:

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)

【讨论】:

  • 非常感谢。您认为不修改“Times”列可以吗?
  • 你不能使用 grouper 除非它是一个有效的类时间类型。
  • 好。那么, datetime.time 对象数组不是有效的类时间类型吗?我仍在努力查看 datetime、datetime.time 和 DateIndex 之间的区别。
  • datetime.time 是对象。它必须是有效的 dtype 才能工作 datetime64[ns]timedelta64[ns] 两者都是时间的数字表示(以纳秒为单位)。重采样操作是基于数学的。这不能用'00:00:01'这个词来完成,但可以用数字1000000000来完成
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-10-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多