我有三列日期,一列Begin
列和两列End
列。我想使用bdate_range
len
来查找Begin
和End
之间的工作日数。但是,在bdate_range
中使用NaT
作为参数会导致它引发错误。
设置
test = pd.DataFrame({'Begin': ['2014-06-11', '2014-08-05', '2014-09-21', '2014-09-21', '2014-09-21', '-'],
'End1': ['2014-06-12', '2014-08-31', 'NaT', '2014-09-30', '2014-09-28', '-'],
'End2': ['2014-06-14', '-', '2014-09-30', '-', '2014-09-28', '2014-12-15']})
test['Begin'] = pd.to_datetime(test['Begin'], dayfirst=False, yearfirst=False, errors='coerce', exact=False)
test['End1'] = pd.to_datetime(test['End1'], dayfirst=False, yearfirst=False, errors='coerce', exact=False)
test['End2'] = pd.to_datetime(test['End2'], dayfirst=False, yearfirst=False, errors='coerce', exact=False)
创建此表:
开始结束1 结束2 0 2014-06-11 2014-06-12 2014-06-14 1 2014-08-05 2014-08-31 NaT 2 2014-09-21 NaT 2014-09-30 3 2014-09-21 2014-09-30 NaT 4 2014-09-21 2014-09-28 2014-09-28 5 NaT NaT 2014-12-15
我的尝试
因此,在这些数据帧中,我尝试了bdate_range
len
test['bdate_range'] = [len(pd.bdate_range(x,y))for x,y in zip(test['Begin'],test['End1'])]
.
.
.
ValueError: Neither `start` nor `end` can be NaT
fillna
不太好...
test = test.fillna(pd.Timedelta(0))
test['bdate_range'] = [len(pd.bdate_range(x,y))for x,y in zip(test['Begin'],test['End1'])]
.
.
.
TypeError: Cannot convert input [0 days 00:00:00] of type <class 'pandas._libs.tslibs.timedeltas.Timedelta'> to Timestamp
期望的结果
理想的结果是再增加两列,每行中还有两个字段:
- 开始 - 结束 1 工作日的差异,如果列的任何值 NaT 结果将为 NaN/NaT
- 开始 - 结束工作日的 2 差异,如果有任何值是 NaT,则这些是 NaT/NaN –
1 结束2 开始End1_bdate开始End2_bdate 0 2014-06-11 2014-06-12 2014-06-14 1 2 1 2014-08-05 2014-08-31 NaT 18 NaN 2 2014-09-21 NaT 2014-09-30 NaN 7 3 2014-09-21 2014-09-30 NaT 7 NaN 4 2014-09-21 2014-09-28 2014-09-28 5 5 5 NaT NaT 2014-12-15
NaNNaN 任何想法?
您需要将该函数(在本例中为bdate_range
的len
)应用于既不Begin
字段也不null
End
字段的行。您可以将默认range
字段设置为null
,然后使用.loc
仅切片到这些特定行。请阅读有关该功能的较长帖子。
### YOUR SETUP CODE
test = pd.DataFrame({'Begin': ['2014-06-11', '2014-08-05', '2014-09-21', '2014-09-21', '2014-09-21', '-'],
'End1': ['2014-06-12', '2014-08-31', 'NaT', '2014-09-30', '2014-09-28', '-'],
'End2': ['2014-06-14', '-', '2014-09-30', '-', '2014-09-28', '2014-12-15']})
test['Begin'] = pd.to_datetime(test['Begin'], dayfirst=False, yearfirst=False, errors='coerce', exact=False)
test['End1'] = pd.to_datetime(test['End1'], dayfirst=False, yearfirst=False, errors='coerce', exact=False)
test['End2'] = pd.to_datetime(test['End2'], dayfirst=False, yearfirst=False, errors='coerce', exact=False)
## DEFAULT RANGE FIELDS TO NULL
test['Begin-End1_bdate'] = np.nan
test['Begin-End2_bdate'] = np.nan
### USE LOC TO FIND NON-NULL ROWS
test.loc[(test['Begin'].notnull()) & (test['End1'].notnull()), 'Begin-End1_bdate'] = test[(test['Begin'].notnull()) & (test['End1'].notnull())].apply(lambda row: len(pd.bdate_range(row['Begin'], row['End1'])), axis = 1)
test.loc[(test['Begin'].notnull()) & (test['End2'].notnull()), 'Begin-End2_bdate'] = test[(test['Begin'].notnull()) & (test['End2'].notnull())].apply(lambda row: len(pd.bdate_range(row['Begin'], row['End2'])), axis = 1)
test