如何更好地处理 Python 中的日期以删除 NaN 并识别两个时间间隔之间的工作日和假期?
How can I work better with dates in Python to remove NaNs and identify workdays and holidays between two intervals?
我有一个包含两个日期字段的数据框,如下所示。我希望能够使用此数据为员工计算 'adjusted pay' - 如果员工在一个月的 15 日之后加入,他们将获得 3 月 15 日的工资 + 4 月 10 日的工资(发薪日) ,同样如果他们在 4 月离开,计算应该只考虑 4 月的工作天数。
Hire_Date | Leaving_Date
_________________________
01/02/2007 | NaN
02/03/2007 | NaN
23/03/2020 | Nan
01/01/1999 | 04/04/2020
哦,上面的数据没有以日期时间格式显示,当然 leaving_date 字段中有很多 NaN :)
因此,我做了以下操作:
将数据转换为日期时间格式,保留日期,并用随机日期填充 N/As(对此不太满意,但这只是在少数记录中缺失,所以不担心影响) .
df['Hire_Date'] = pd.to_datetime(df['Hire_Date'])
df['Hire_Date'] = [a.date() for a in df['Hire_Date']]
df['Hire_Date'] = df['Hire_Date'].fillna('1800-01-01')
重复离开日期。这里唯一的区别是我用 0 填充了 NaN,因为我们没有那么多离开者。
df['Leaving_Date'] = pd.to_datetime(df['Leaving_Date'])
df['Leaving_Date'] = [a.date() for a in df['Leaving_Date']]
df['Leaving_Date'] = df['Leaving_Date'].fillna('0')
然后我创建了一个新的专栏来记录工作日,这就是我 运行 进入这个问题的地方。我的代码如下。
我确定了雇用月份的第一天,并尝试使用 np.where()
函数计算出三月份的工作天数。
df['z_First_Day_H_Month'] = df['Hire_Date'].values.astype('datetime64[M]')
df['March_Workdays'] = np.where((df['z_First_Day_H_Month'] >= '2020-03-01'),
(np.busday_count(df['z_First_Day_H_Month'], '2020-03-31')), 'N/A')
重复类似的过程,但计算终止月份的工作天数的计算更简单。
df['z_First_Day_T_Month'] = df.apply(lambda x: '2020-04-01').astype('datetime64[M]')
df['T_Mth_Workdays'] = df.apply(lambda x: np.busday_count(x['z_First_Day_T_Month'],
x['Leaving_Date'])
但是上面的过程returns出现如下错误:
iterator operand 0 dtype could not be cast from dtype(' m8 [ns] ') to dtype(' m8 [d] according to rule 'safe' ')
我能得到一些帮助来解决这个问题吗?谢谢!
我做了一些研究,似乎日期时间格式可能有问题。 [ns] 格式精度为纳秒,np.busday_count
要求日期格式,即 [D],导致错误。查看 this numpy document 并检查日期时间单位部分。
Numpy, TypeError: Could not be cast from dtype('<M8[us]') to dtype('<M8[D]')
看看这个post。和你的问题一模一样!
我有一个包含两个日期字段的数据框,如下所示。我希望能够使用此数据为员工计算 'adjusted pay' - 如果员工在一个月的 15 日之后加入,他们将获得 3 月 15 日的工资 + 4 月 10 日的工资(发薪日) ,同样如果他们在 4 月离开,计算应该只考虑 4 月的工作天数。
Hire_Date | Leaving_Date
_________________________
01/02/2007 | NaN
02/03/2007 | NaN
23/03/2020 | Nan
01/01/1999 | 04/04/2020
哦,上面的数据没有以日期时间格式显示,当然 leaving_date 字段中有很多 NaN :)
因此,我做了以下操作:
将数据转换为日期时间格式,保留日期,并用随机日期填充 N/As(对此不太满意,但这只是在少数记录中缺失,所以不担心影响) .
df['Hire_Date'] = pd.to_datetime(df['Hire_Date'])
df['Hire_Date'] = [a.date() for a in df['Hire_Date']]
df['Hire_Date'] = df['Hire_Date'].fillna('1800-01-01')
重复离开日期。这里唯一的区别是我用 0 填充了 NaN,因为我们没有那么多离开者。
df['Leaving_Date'] = pd.to_datetime(df['Leaving_Date'])
df['Leaving_Date'] = [a.date() for a in df['Leaving_Date']]
df['Leaving_Date'] = df['Leaving_Date'].fillna('0')
然后我创建了一个新的专栏来记录工作日,这就是我 运行 进入这个问题的地方。我的代码如下。
我确定了雇用月份的第一天,并尝试使用 np.where()
函数计算出三月份的工作天数。
df['z_First_Day_H_Month'] = df['Hire_Date'].values.astype('datetime64[M]')
df['March_Workdays'] = np.where((df['z_First_Day_H_Month'] >= '2020-03-01'),
(np.busday_count(df['z_First_Day_H_Month'], '2020-03-31')), 'N/A')
重复类似的过程,但计算终止月份的工作天数的计算更简单。
df['z_First_Day_T_Month'] = df.apply(lambda x: '2020-04-01').astype('datetime64[M]')
df['T_Mth_Workdays'] = df.apply(lambda x: np.busday_count(x['z_First_Day_T_Month'],
x['Leaving_Date'])
但是上面的过程returns出现如下错误:
iterator operand 0 dtype could not be cast from dtype(' m8 [ns] ') to dtype(' m8 [d] according to rule 'safe' ')
我能得到一些帮助来解决这个问题吗?谢谢!
我做了一些研究,似乎日期时间格式可能有问题。 [ns] 格式精度为纳秒,np.busday_count
要求日期格式,即 [D],导致错误。查看 this numpy document 并检查日期时间单位部分。
Numpy, TypeError: Could not be cast from dtype('<M8[us]') to dtype('<M8[D]')
看看这个post。和你的问题一模一样!