次を使用できます。
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
とによって両方の列を日時に変換しますto_datetime
DataFrame.melt
-DataFrameGroupBy.resample
グループごとに可能DataFrame.assign
のすべての値を設定するためval
に1
、によって日付Series.dt.date
とSeries.dt.hour
DataFrame.set_index
とSeries.unstack
DataFrame.reset_index
とDataFrame.rename_axis
編集:
時間の開始と終了については、同様のソリューションを使用します。時間については、フロア時間をSeries.dt.floor
減算し1
、開始日も減算する場合は、次のように使用first
し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]
編集1:アイデアは分単位でリサンプリングしてから時間を集計します:
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
この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。
侵害の場合は、連絡してください[email protected]
コメントを追加