将包含日期时间范围的Pandas数据框行转换为新数据框,其中每个日期行以及该日期包含的小时

时间:2019-02-12 17:54:22

标签: python pandas dataframe

因此,我在数据框中有StartDateTime和EndDateTime列,并且我想生成一个新的数据框,其中在datetime范围内的每个日期都带有一行,但是我还希望该日期中包含的小时数日期范围。

In [11]: sessions = pd.DataFrame({'Start':['2018-01-01 13:00:00','2018-03-01 16:30:00'],
'End':['2018-01-03 07:00:00','2018-03-02 06:00:00'],'User':['Dan','Fred']})
In [12]: sessions
Out[12]:    
                Start                 End User
0 2018-01-01 13:00:00 2018-01-03 07:00:00  Dan 
1 2018-03-01 16:30:00 2018-03-02 06:00:00 Fred 

所需数据框:

Date        Hours   User
2018-01-01  11      Dan
2018-01-02  24      Dan
2018-01-02  7       Dan
2018-03-01  7.5     Fred
2018-03-02  6       Fred

我看过很多例子,它们只是为日期范围内的每个日期生成了一个数据框(例如Expanding pandas data frame with date range in columns) 但范围内未包含每个日期的额外小时数。

2 个答案:

答案 0 :(得分:0)

我不知道这是最干净的解决方案,但它似乎可行。

3D visualization device system

Description
3D real-time rendering system.
Usage
# Low level rgl.* interface
rgl.open(useNULL = rgl.useNULL())     # open new device
rgl.close()    # close current device

将开始和结束转换为日期时间

In [13]: sessions = pd.DataFrame({'Start':['2018-01-01 13:00:00','2018-03-01 16:30:00'],
'End':['2018-01-03 07:00:00','2018-03-02 06:00:00'],'User':['Dan','Fred']})

为范围中的每个日期创建一行

In [14]: sessions['Start']=pd.to_datetime(sessions['Start'])
    sessions['End']=pd.to_datetime(sessions['End'])

用于根据开始日期时间,结束日期时间和特定日期计算日期时间的功能

In [15]: dailyUsage = pd.concat([pd.DataFrame({'Date': 
pd.date_range(pd.to_datetime(row.Start).date(), row.End.date(), freq='D'),'Start':row.Start,
               'User': row.User,
               'End': row.End}, columns=['Date', 'Start','User', 'End']) 
           for i, row in sessions.iterrows()], ignore_index=True)

计算每个日期的小时数

In [16]: def calcDuration(x):
    date=  x['Date']
    startDate = x['Start']
    endDate = x['End']

    #starts and stops on same day
    if endDate.date() == startDate.date():
        return (endDate - startDate).seconds/3600

    #this is on the start date
    if (date.to_pydatetime().date() - startDate.date()).days == 0:
        return 24 - startDate.hour

    #this is on the end date
    if (date.to_pydatetime().date() - endDate.date()).days == 0:
        return startDate.hour

    #this is on an interior date
    else:
        return 24

答案 1 :(得分:0)

如果您不只看整数,这样的事情也可以工作;

df['date'] = df['Date'].dt.date
gb = df.groupby(['date', 'User'])['Date'].size()
print(gb)

date        User
2018-01-01  Dan     11
2018-01-02  Dan     24
2018-01-03  Dan      8
2018-03-01  Fred     8
2018-03-02  Fred     6
Name: Date, dtype: int64