两天之间的差异(不包括周末的小时数)

时间:2019-08-02 06:18:22

标签: python pandas dataframe timestamp timedelta

我有一个代码,可以使用np.busdaycount计算不包括周末的日期差异,但是我需要在我无法获得的小时数内。

import datetime
import numpy as np


df.Inflow_date_time= [pandas.Timestamp('2019-07-22 21:11:26')]
df.End_date_time= [pandas.Timestamp('2019-08-02 11:44:47')]

df['Day'] = ([np.busday_count(b,a) for a, b in zip(df['End_date_time'].values.astype('datetime64[D]'),df['Inflow_date_time'].values.astype('datetime64[D]'))])

  Day
0  9

除周末外,我的工作时间为小时。喜欢

  Hours
0  254

问题

Inflow_date_time = 2019-08-01 23:22:46 结束日期时间= 2019-08-05 17:43:51 预期时间42小时 (1 + 24 + 17)

Inflow_date_time = 2019-08-03 23:22:46 结束日期时间= 2019-08-05 17:43:51
预计时间17小时 (0 + 0 + 17)

Inflow_date_time = 2019-08-01 23:22:46 结束日期时间= 2019-08-05 17:43:51 预计时间17小时 (0 + 0 + 17)

Inflow_date_time = 2019-07-26 23:22:46 结束日期时间= 2019-08-05 17:43:51
预计时间138小时 (1 + 120 + 17)

Inflow_date_time = 2019-08-05 11:22:46 结束日期时间= 2019-08-05 17:43:51
预期时间6小时 (0 + 0 + 6)

请提出建议。

2 个答案:

答案 0 :(得分:2)

想法是按日期逐个删除times并按numpy.busday_counthours3列中获取开始日期+一日之间的营业日数,然后创建{{1} }和hour1列中的开始和结束时间,如果不是周末,则以小时为单位。最后汇总所有小时数列:

hour2

df = pd.DataFrame(columns=['Inflow_date_time','End_date_time', 'need'])
df.Inflow_date_time= [pd.Timestamp('2019-08-01 23:22:46'),
                      pd.Timestamp('2019-08-03 23:22:46'),
                      pd.Timestamp('2019-08-01 23:22:46'),
                      pd.Timestamp('2019-07-26 23:22:46'),
                      pd.Timestamp('2019-08-05 11:22:46')]
df.End_date_time= [pd.Timestamp('2019-08-05 17:43:51')] * 5
df.need = [42,17,41,138,6]

#print (df)

df["hours1"] = df["Inflow_date_time"].dt.ceil('d')
df["hours2"] =  df["End_date_time"].dt.floor('d')
one_day_mask = df["Inflow_date_time"].dt.floor('d') == df["hours2"]

df['hours3'] = [np.busday_count(b,a)*24 for a, b in zip(df['hours2'].dt.strftime('%Y-%m-%d'),
                                                        df['hours1'].dt.strftime('%Y-%m-%d'))]

mask1 = df['hours1'].dt.dayofweek < 5
hours1 = df['hours1']  - df['Inflow_date_time'].dt.floor('H')

df['hours1'] = np.where(mask1, hours1, np.nan) / np.timedelta64(1 ,'h')

mask2 = df['hours2'].dt.dayofweek < 5

df['hours2'] = (np.where(mask2, df['End_date_time'].dt.floor('H')-df['hours2'], np.nan) / 
                np.timedelta64(1 ,'h'))

df['date_diff'] = df['hours1'].fillna(0) + df['hours2'].fillna(0) + df['hours3']

one_day = (df['End_date_time'].dt.floor('H') - df['Inflow_date_time'].dt.floor('H')) / 
            np.timedelta64(1 ,'h')
df["date_diff"] = df["date_diff"].mask(one_day_mask, one_day)

答案 1 :(得分:0)

如果我没有完全错,也可以使用更短的解决方法:

首先将您的日差保存在数组中:

res = np.busday_count(df['Inflow_date_time'].values.astype('datetime64[D]'), df['End_date_time'].values.astype('datetime64[D]'))

然后,我们需要为每一行增加一个小时栏:

df['starth'] = df['Inflow_date_time'].dt.hour
df['endh'] = df['End_date_time'].dt.hour

然后,我们将为您的数据框获取日差:

my_list = res.tolist()
dfhelp =pd.DataFrame(my_list,columns=['col1'])
df2 = pd.concat((df, df2) , axis=1)

然后我们必须获得一个帮助列,因为End_date_time的时间可能早于Inflow_date-time

df2['h'] = df2['endh']-df2['starth']

然后我们可以计算时差(一天的24小时,取决于结束日期的小时是否早于开始小时的日期):

df2['differenceh'] = np.where(df2['h'] >= 0, df2['col1']*24+df2['h'], df2['col1']*24-24+(24+df2['h']))