python - 有没有办法在 python pandas 中将基于时间的事件划分为小时模板?
问题描述
我想要一个输出数据框,它是一个小时模板(列中的小时数)和具有相同事件的不同行中的日期。并且要为相应的小时和日期填充的值是“1”。
任何帮助,将不胜感激。
解决方案
您可以使用:
df = pd.DataFrame({
'Event':list('abc'),
'StartTime':['24-12-19 1:14','22-12-19 0:32','23-12-19 6:00'],
'EndTime':['24-12-19 6:00','24-12-19 4:32','24-12-19 16:00']
})
df[['StartTime','EndTime']] = df[['StartTime','EndTime']].apply(pd.to_datetime, dayfirst=True)
df1 = (df.melt('Event')
.set_index('value')
.groupby('Event')['Event']
.resample('H')
.count()
.reset_index(name='val')
.assign(val=1,
date=lambda x: x['value'].dt.date,
hour=lambda x: x['value'].dt.hour)
.set_index(['Event','date','hour'])['val']
.unstack(fill_value=0)
.reset_index()
.rename_axis(None, axis=1)
)
print (df1)
Event date 0 1 2 3 4 5 6 7 ... 14 15 16 17 18 19 20 \
0 a 2019-12-24 0 1 1 1 1 1 1 0 ... 0 0 0 0 0 0 0
1 b 2019-12-22 1 1 1 1 1 1 1 1 ... 1 1 1 1 1 1 1
2 b 2019-12-23 1 1 1 1 1 1 1 1 ... 1 1 1 1 1 1 1
3 b 2019-12-24 1 1 1 1 1 0 0 0 ... 0 0 0 0 0 0 0
4 c 2019-12-23 0 0 0 0 0 0 1 1 ... 1 1 1 1 1 1 1
5 c 2019-12-24 1 1 1 1 1 1 1 1 ... 1 1 1 0 0 0 0
21 22 23
0 0 0 0
1 1 1 1
2 1 1 1
3 0 0 0
4 1 1 1
5 0 0 0
[6 rows x 26 columns]
说明:
DataFrame.apply
首先通过and将两列转换为日期时间to_datetime
- 重塑
DataFrame.melt
-DataFrameGroupBy.resample
每组都有可能 DataFrame.assign
使用for 设置所有值val
to1
、 dates bySeries.dt.date
和创建新列Series.dt.hour
DataFrame.set_index
最后通过and重塑Series.unstack
- 最后一些数据清理
DataFrame.reset_index
和DataFrame.rename_axis
编辑:
对于小时的开始和结束,使用类似的解决方案 - 对于小时减去下限小时Series.dt.floor
,如果开始日期也减去1
,则使用first
with resample
:
#changed times
df = pd.DataFrame({
'Event':list('abc'),
'StartTime':['24-12-19 1:20','22-12-19 0:30','23-12-19 6:00'],
'EndTime':['24-12-19 6:20','24-12-19 4:40','24-12-19 16:00']
})
df[['StartTime','EndTime']] = df[['StartTime','EndTime']].apply(pd.to_datetime, dayfirst=True)
f = lambda x: x['value'].sub(x['value'].dt.floor('H')).dt.total_seconds().div(3600)
df1 = (df.melt('Event')
.assign(h = f)
.assign(h = lambda x: x.h.mask(x.variable == 'StartTime', 1 - x.h))
.set_index('value')
.groupby('Event')['h']
.resample('H')
.first()
.fillna(1)
.reset_index(name='h')
.assign(date=lambda x: x['value'].dt.date,
hour=lambda x: x['value'].dt.hour)
.set_index(['Event','date','hour'])['h']
.unstack(fill_value=0)
.reset_index()
.rename_axis(None, axis=1)
)
print (df1)
Event date 0 1 2 3 4 5 6 7 \
0 a 2019-12-24 0.0 0.666667 1.0 1.0 1.000000 1.0 0.333333 0.0
1 b 2019-12-22 0.5 1.000000 1.0 1.0 1.000000 1.0 1.000000 1.0
2 b 2019-12-23 1.0 1.000000 1.0 1.0 1.000000 1.0 1.000000 1.0
3 b 2019-12-24 1.0 1.000000 1.0 1.0 0.666667 0.0 0.000000 0.0
4 c 2019-12-23 0.0 0.000000 0.0 0.0 0.000000 0.0 1.000000 1.0
5 c 2019-12-24 1.0 1.000000 1.0 1.0 1.000000 1.0 1.000000 1.0
14 15 16 17 18 19 20 21 22 23
0 ... 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0
1 ... 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0
2 ... 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0
3 ... 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0
4 ... 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0
5 ... 1.0 1.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0
[6 rows x 26 columns]
EDIT1:想法按分钟重新采样,然后汇总小时:
df = pd.DataFrame({
'Event':list('abc'),
'StartTime':['20-12-19 18:06','22-12-19 0:32','23-12-19 6:00'],
'EndTime':['20-12-19 18:07','24-12-19 4:32','24-12-19 16:00']
})
df[['StartTime','EndTime']] = df[['StartTime','EndTime']].apply(pd.to_datetime, dayfirst=True)
f = lambda x: x['value'].sub(x['value'].dt.floor('Min')).dt.total_seconds().div(60)
df1 = (df.melt('Event')
.assign(h = f)
.assign(h = lambda x: x.h.mask(x.variable == 'StartTime', 1 - x.h))
.set_index('value')
.groupby('Event')['h']
.resample('Min')
.first()
.fillna(1)
.reset_index(name='h')
.assign(date=lambda x: x['value'].dt.date,
hour=lambda x: x['value'].dt.hour)
.groupby(['Event','date','hour'])['h']
.sum()
.unstack(fill_value=0)
.div(60)
.reset_index()
.rename_axis(None, axis=1)
)
print (df1)
Event date 0 1 2 3 4 5 6 7 8 \
0 a 2019-12-20 0.000000 0.0 0.0 0.0 0.000000 0.0 0.0 0.0 0.0
1 b 2019-12-22 0.466667 1.0 1.0 1.0 1.000000 1.0 1.0 1.0 1.0
2 b 2019-12-23 1.000000 1.0 1.0 1.0 1.000000 1.0 1.0 1.0 1.0
3 b 2019-12-24 1.000000 1.0 1.0 1.0 0.533333 0.0 0.0 0.0 0.0
4 c 2019-12-23 0.000000 0.0 0.0 0.0 0.000000 0.0 1.0 1.0 1.0
5 c 2019-12-24 1.000000 1.0 1.0 1.0 1.000000 1.0 1.0 1.0 1.0
9 10 11 12 13 14 15 16 17 18 19 20 21 22 \
0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.016667 0.0 0.0 0.0 0.0
1 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.000000 1.0 1.0 1.0 1.0
2 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.000000 1.0 1.0 1.0 1.0
3 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.000000 0.0 0.0 0.0 0.0
4 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.000000 1.0 1.0 1.0 1.0
5 1.0 1.0 1.0 1.0 1.0 1.0 1.0 0.0 0.0 0.000000 0.0 0.0 0.0 0.0
23
0 0.0
1 1.0
2 1.0
3 0.0
4 1.0
5 0.0
推荐阅读
- python - 将一列json字符串转换为数据列(API结果/输出)
- react-native - 无法理解我的应用程序上的 React-native 错误
- javascript - 在某些 div 中显示 antd 模态掩码
- java - 我可以为多个测试类使用相同的参数化数据吗
- php - “使用按钮更新记录的问题”
- python - 用熊猫将Excel工作表(Listobject)读入python
- python - 为 MNIST 数据集运行自定义 Tensorflow 训练循环时出现 OOM 错误
- rust - 使用 MALLOC_MMAP_THRESHOLD_ 从 mmap 分配大型结构
- javascript - 我的按钮(EventListener)只有有限的点击
- git - Github 上传项目(推送问题)