我有一个数据帧:
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)
结果仅在列名上不同。