Pandas 将按开始和结束数据绑定的每小时标记数据分组到按比例使用DF的每日数据

Pandas 将按开始和结束数据绑定的每小时标记数据分组到按比例使用DF的每日数据,pandas,Pandas,我使用的是每个产品的不可用性数据,在产品不可用的每个时段都有每小时的开始和结束时间,以下是一个示例: import pandas as pd import datetime as dt unavability = pd.DataFrame([[dt.datetime(2017, 10, 19,11), dt.datetime(2017, 10, 19,12),'broom'], [dt.datetime(2017, 10, 19,9),dt.date

我使用的是每个产品的不可用性数据,在产品不可用的每个时段都有每小时的开始和结束时间,以下是一个示例:

import pandas as pd
import datetime as dt
unavability = pd.DataFrame([[dt.datetime(2017, 10, 19,11), dt.datetime(2017, 10, 19,12),'broom'],
                       [dt.datetime(2017, 10, 19,9),dt.datetime(2017, 10, 19,10),'broom'], 
                       [dt.datetime(2017, 10, 19,1), dt.datetime(2017, 10, 19,2),'bike'],
                       [dt.datetime(2017, 10, 19,22),dt.datetime(2017, 10, 20,3),'bike']],
                      columns=['start_date', 'end_date','product'])
print unavability
      start_date            end_date product
0 2017-10-19 11:00:00 2017-10-19 12:00:00   broom
1 2017-10-19 09:00:00 2017-10-19 10:00:00   broom
2 2017-10-19 01:00:00 2017-10-19 02:00:00    bike
3 2017-10-19 22:00:00 2017-10-20 03:00:00    bike
我希望将数据分组为每个日期和产品的不可用比例,因此我想将上面的数据框转换为以下内容,请记住,即使不可用时间超过49小时,重叠3天,我也希望它能够工作

desired=pd.DataFrame([[dt.datetime(2017, 10, 19),'broom',22/24.0],#2 houres of unavalability
              [dt.datetime(2017, 10, 20),'broom',24/24.0], #Product fully available at that day
              [dt.datetime(2017, 10, 19),'bike',22/24.0], # 2 hour of unavalability - from 22 to 24
              [dt.datetime(2017, 10, 20),'bike',21/24.0]], # 3 hour of unavalability - from 00 to 3
              columns=['date', 'product','avalability_proportion'])
print desired
        date product  avalability_proportion
0 2017-10-19   broom                0.916667
1 2017-10-20   broom                1.000000
2 2017-10-19    bike                0.916667
3 2017-10-20    bike                0.875000
一些强人: 我想先创建一个转换,为所有可用的产品创建这里建议的理论时间:,然后创建一个原始数据的连接,以及如何填充它,不确定这是否明智


在这方面的任何帮助都会很棒,提前谢谢

我愚蠢的解决方案,希望这能有所帮助:

df = unavability
# if date is changed, remember changed rows
df['is_date_changed'] = df.start_date.dt.date != df.end_date.dt.date
df.loc[df.is_date_changed,'intermediate_date'] = pd.to_datetime(df.end_date.dt.date)
df_date_is_changed = df.loc[df.is_date_changed]
df_date_not_changed = df.loc[~df.is_date_changed]

# expand every changed row to two, 
# and append those rows to the date_not_changed dataframe.
# for example,
# 2017-10-19 22:00:00   2017-10-20 03:00:00
# will be expand into two rows:
# 2017-10-19 22:00:00   2017-10-20 00:00:00
# 2017-10-20 00:00:00   2017-10-20 03:00:00
for idx,row in df_date_is_changed.iterrows():
    row1 = [row['start_date'],row['intermediate_date'],row['product'],None,None]
    df_date_not_changed.loc[-1] = row1
    df_date_not_changed.index = df_date_not_changed.index + 1
    row2 = [row['intermediate_date'],row['end_date'],row['product'],None,None]
    df_date_not_changed.loc[-1] = row2
    df_date_not_changed.index = df_date_not_changed.index + 1

df = df_date_not_changed
df['date'] = df.apply(
    lambda x:min(x['start_date'],x['end_date']),
axis=1)
df.date = df.date.dt.date
df['time_delta'] = df.end_date - df.start_date

df.groupby(['product','date']).agg({'time_delta':'sum'})

感谢您的回答,不过请记住,您将数据拆分为两个帧,用于接下来的两个日期,如果持续3天不可用,会发生什么情况?您可以附加更多行,每行代表一天。但也许它看起来很愚蠢。你必须考虑时间窗重叠。还要注意,我想要一列比例,而不是时间差,我想要它作为24小时的比例,而不是时间差:这个比例可以根据时间差来计算,所以我忽略它。