Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/360.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在python中有没有办法将基于时间的事件划分为小时模板?_Python_Pandas_Datetime_Time - Fatal编程技术网

在python中有没有办法将基于时间的事件划分为小时模板?

在python中有没有办法将基于时间的事件划分为小时模板?,python,pandas,datetime,time,Python,Pandas,Datetime,Time,我有一个包含各种事件的数据帧,包括开始时间和结束时间。 例如 我想要一个输出数据框,它是一个小时模板,列中为小时,行中为日期,具有相同的事件。将相应的小时和日期的值填充为“1” 任何帮助都将不胜感激。这里有一种方法可以做到这一点: # sample data d = pd.DataFrame({'Event': ['Event1','Event2'], 'StartTime':['2019-01-01 00:10:00', '2019-01-01 13:10

我有一个包含各种事件的数据帧,包括开始时间和结束时间。 例如

我想要一个输出数据框,它是一个小时模板,列中为小时,行中为日期,具有相同的事件。将相应的小时和日期的值填充为“1”


任何帮助都将不胜感激。

这里有一种方法可以做到这一点:

# sample data
d = pd.DataFrame({'Event': ['Event1','Event2'],
                  'StartTime':['2019-01-01 00:10:00', '2019-01-01 13:10:00'],
                  'EndTime':['2019-01-01 11:10:00', '2019-01-01 20:10:00']})

# convert cols to datetime
col = ['StartTime','EndTime']
for c in col:
    d[c] = pd.to_datetime(d[c])

# add a new column containing list of hours
d['hours'] = [[x for x in range(24)] for _ in range(d.shape[0])]

# explode the list into new rows
d = d.explode('hours').reset_index(drop=True)

# calculate the values for each hour
def make_table(f):
    start_hour = int(f['StartTime'].dt.hour.unique())
    hour_diff = (f['EndTime'] - f['StartTime']).astype('timedelta64[h]').tolist()
    max_hour = int(f['EndTime'].dt.hour.unique())
    use_hours = [x for x in range(start_hour, max_hour+1)]
    f['encode'] = f['hours'].apply(lambda x: 1 if x in use_hours else 0)
    return f

# apply the function to each group
d2 = d.groupby(['Event','StartTime','EndTime']).apply(make_table)

# convert d2 into wide format using pivot
d2 = pd.pivot_table(d2, values='encode', index=['Event','StartTime','EndTime'], columns=['hours'])
下面是输出的样子,只显示了几列

hours                                           0  1  2  3  4  5  6 ...
Event  StartTime           EndTime                                 
Event1 2019-01-01 00:10:00 2019-01-01 11:10:00  1  1  1  1  1  1  1 ...
Event2 2019-01-01 13:10:00 2019-01-01 20:10:00  0  0  0  0  0  0  0 ...

以下是一种方法:

# sample data
d = pd.DataFrame({'Event': ['Event1','Event2'],
                  'StartTime':['2019-01-01 00:10:00', '2019-01-01 13:10:00'],
                  'EndTime':['2019-01-01 11:10:00', '2019-01-01 20:10:00']})

# convert cols to datetime
col = ['StartTime','EndTime']
for c in col:
    d[c] = pd.to_datetime(d[c])

# add a new column containing list of hours
d['hours'] = [[x for x in range(24)] for _ in range(d.shape[0])]

# explode the list into new rows
d = d.explode('hours').reset_index(drop=True)

# calculate the values for each hour
def make_table(f):
    start_hour = int(f['StartTime'].dt.hour.unique())
    hour_diff = (f['EndTime'] - f['StartTime']).astype('timedelta64[h]').tolist()
    max_hour = int(f['EndTime'].dt.hour.unique())
    use_hours = [x for x in range(start_hour, max_hour+1)]
    f['encode'] = f['hours'].apply(lambda x: 1 if x in use_hours else 0)
    return f

# apply the function to each group
d2 = d.groupby(['Event','StartTime','EndTime']).apply(make_table)

# convert d2 into wide format using pivot
d2 = pd.pivot_table(d2, values='encode', index=['Event','StartTime','EndTime'], columns=['hours'])
下面是输出的样子,只显示了几列

hours                                           0  1  2  3  4  5  6 ...
Event  StartTime           EndTime                                 
Event1 2019-01-01 00:10:00 2019-01-01 11:10:00  1  1  1  1  1  1  1 ...
Event2 2019-01-01 13:10:00 2019-01-01 20:10:00  0  0  0  0  0  0  0 ...
您可以使用:

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)
        )
说明:

首先通过和将两列转换为datetimes 按组进行重塑-以便可能 创建新列,将val的所有值设置为1、日期和 最后通过和进行整形 最后通过和进行一些数据清理 编辑:

对于工作时间的开始和结束,使用类似的解决方案-对于工作时间,减去最低工作时间,如果开始日期也减去1,则首先使用重采样:

EDIT1:Idea是按分钟重新采样,然后再聚合小时数:

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 = 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)
        )
说明:

首先通过和将两列转换为datetimes 按组进行重塑-以便可能 创建新列,将val的所有值设置为1、日期和 最后通过和进行整形 最后通过和进行一些数据清理 编辑:

对于工作时间的开始和结束,使用类似的解决方案-对于工作时间,减去最低工作时间,如果开始日期也减去1,则首先使用重采样:

EDIT1:Idea是按分钟重新采样,然后再聚合小时数:

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']
})

有没有办法将值添加为“小时”而不是1?例如,如果开始时间是12:30,我想在13号得到0.5hour@SuhasMucherla-可能,但更复杂。每组的最后一个值应该是多少?e、 g.如果24-12-19 10:22?它应该是22/60?是的,基本上我想要的是活动在特定时间的活动时间,以小时为单位。因此,如果它是组中的最后一个值,则为22/60,如果它是组中的第一个值,则为38/60如果事件的开始时间和结束时间在同一小时内,则上述解决方案似乎不起作用,例如,如果开始时间为24-12-19 18:06,结束时间为24-12-19 18:07,则我希望18小时列具有1/60。但这似乎没有发生,有什么解决办法吗?有没有办法将值添加为“小时”而不是1?例如,如果开始时间是12:30,我想在13号得到0.5hour@SuhasMucherla-可能,但更复杂。每组的最后一个值应该是多少?e、 g.如果24-12-19 10:22?它应该是22/60?是的,基本上我想要的是活动在特定时间的活动时间,以小时为单位。因此,如果它是组中的最后一个值,则为22/60,如果它是组中的第一个值,则为38/60如果事件的开始时间和结束时间在同一小时内,则上述解决方案似乎不起作用,例如,如果开始时间为24-12-19 18:06,结束时间为24-12-19 18:07,则我希望18小时列具有1/60。但这似乎没有发生,有什么解决办法吗?
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