将"bdate_range"与空值(NaN,NaT)一起使用



我有三列日期,一列Begin列和两列End列。我想使用bdate_rangelen来查找BeginEnd之间的工作日数。但是,在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_rangelen

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. 开始 - 结束 1 工作日的差异,如果列的任何值 NaT 结果将为 NaN/NaT
  2. 开始 - 结束工作日的 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_rangelen)应用于既不Begin字段也不nullEnd字段的行。您可以将默认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

最新更新