如何在熊猫数据帧中计算一天中的开始小时、一天中的结束小时、每天的平均小时数?



我有一个数据帧:

timestamps                                   values
2017-07-18 20:06:13                            12
2017-07-18 20:08:52                            34
2017-07-19 12:34:02                            123
2017-07-19 12:34:03                            34
2017-07-19 13:11:51                            33
2017-07-19 13:22:08                            76
2017-07-19 22:57:55                            44
2017-07-20 10:34:30                            443
2017-07-20 10:54:00                            32
2017-07-20 11:03:24                            22
2017-07-20 12:05:11                            44
2017-07-20 12:17:28                            323
2017-07-20 12:28:56                            33

时间戳列是日期时间64[ns]。我需要在时间戳列中找到每天的开始小时,在时间戳列中找到每个最后小时,每天的平均计数小时数。

我还使用了 groupby(),我需要按天和小时设置索引和分组行:

df = df.set_index('timestamps')
df.groupby([df.index.day,df.index.hour]).count()

我得到了这个结果:

values 
timestamps timestamps         
18            20                  2 
19            12                  2 
13                  2 
22                  1 
20            10                  2 
11                  1 
12                  3 

我无法在数据帧索引中提取每天的开始小时、每个最后一小时和每天的平均计数小时数。我怎样才能得到这个?感谢任何建议。

IIUC 你可以试试这个:

df['timestamps'] = pd.to_datetime(df['timestamps'])
df['hour'] = df['timestamps'].dt.hour
df.groupby(df['timestamps'].dt.day).agg({'hour': ['min', 'max', 'mean']}) 
.stack(level=0).droplevel(1)

min max mean
timestamps          
18      20  20  20.000000
19      12  22  14.400000
20      10  12  11.166667

为了提供更具启发性的示例,我定义了测试数据帧不同月份的日期(也从八月开始):

df = pd.DataFrame(data=[
[ '2017-07-18 20:06:13',  12 ],
[ '2017-07-18 20:08:52',  34 ],
[ '2017-07-19 12:34:02', 123 ],
[ '2017-07-19 12:34:03',  34 ],
[ '2017-07-19 13:11:51',  33 ],
[ '2017-07-19 13:22:08',  76 ],
[ '2017-07-19 22:57:55',  44 ],
[ '2017-07-20 10:34:30', 443 ],
[ '2017-07-20 10:54:00',  32 ],
[ '2017-07-20 11:03:24',  22 ],
[ '2017-07-20 12:05:11',  44 ],
[ '2017-07-20 12:17:28', 323 ],
[ '2017-07-20 12:28:56',  33 ],
[ '2017-08-20 11:01:00', 122 ],
[ '2017-08-20 13:55:58',  44 ]],
columns=['timestamps', 'values'])
df['timestamps'] = pd.to_datetime(df['timestamps'])

要计算所需的值,请定义要计算的函数 特定日期的最小时间和最大时间之间的小时数:

def fn(row):
return (row['max'] - row['min']) / np.timedelta64(1, 'h')

然后运行:

dayLimits = df.groupby(df.timestamps.dt.floor('d'))
.agg({'timestamps': [min, max]})
dayLimits.columns = dayLimits.columns.droplevel(0)
dayLimits['hrs'] = dayLimits.apply(fn, axis=1)

此代码:

  • 按日期对DF进行分组,
  • 从每个组取最小和最大时间戳,
  • 删除列多索引的顶层,
  • 生成HRS列,应用上述定义的函数。

对于我的测试数据,结果是:

min                 max        hrs
timestamps                                                   
2017-07-18 2017-07-18 20:06:13 2017-07-18 20:08:52   0.044167
2017-07-19 2017-07-19 12:34:02 2017-07-19 22:57:55  10.398056
2017-07-20 2017-07-20 10:34:30 2017-07-20 12:28:56   1.907222
2017-08-20 2017-08-20 11:01:00 2017-08-20 13:55:58   2.916111

而现在,每天有小时数,平均 每天的小时数,您可以计算为:

dayLimits.hrs.mean()

最后是关于其他答案之一的说明:

dt.day分组是错误的,因为例如从第 20 天开始的行每个月都是同一组的成员。

如果你有一个月份的日期,这并不明显,但是在我的测试数据帧上尝试此代码,以便您看到它。

编辑

列的名称应不是Python的保留字或例如函数名称。

因此,考虑到上述因素,其他解决方案可以是:

dayLimits = df.groupby(df.timestamps.dt.floor('d'))
.agg({'timestamps': [min, max]})
dayLimits.columns = ['tmin', 'tmax']
dayLimits['hrs'] = dayLimits.apply(lambda row:
(row.tmax - row.tmin) / np.timedelta64(1, 'h'), axis=1)

结果仅在列名上不同。

最新更新