Pandas 根据大熊猫的具体情况,以天为单位的时差
我有一个如下所示的数据框Pandas 根据大熊猫的具体情况,以天为单位的时差,pandas,pandas-groupby,Pandas,Pandas Groupby,我有一个如下所示的数据框 ID CONSTRUCTION_DATE START_DATE END_DATE CANCELLED_DATE 1 2016-02-06 2016-02-26 2017-02-26 NaT 1 2016-02-06 2017-03-27 2018-02-26 2017-05-22 1 2016-02-06 2017-08-27 2019-02-26
ID CONSTRUCTION_DATE START_DATE END_DATE CANCELLED_DATE
1 2016-02-06 2016-02-26 2017-02-26 NaT
1 2016-02-06 2017-03-27 2018-02-26 2017-05-22
1 2016-02-06 2017-08-27 2019-02-26 2017-10-21
1 2016-02-06 2018-07-27 2021-02-26 NaT
2 2016-05-06 2017-03-27 2018-02-26 NaT
2 2016-05-06 2018-08-27 2019-02-26 NaT
以上数据必须是基于ID和开始日期的订单
从上面的数据框中,我想准备下面的数据框
ID D_from_C_to_first_S_D T_D_V_aft_c T_D_V_w_cancel N_of_cancel Lst_END_DATE_to_today
1 20 376 29 2 After_today
1 325 NaN 182 0 358
在哪里
取消日期=NaT表示合同未取消
D_from_C_to_first_S_D=从施工日期到首次开工日期的天数
T_D_V_aft_c=ID=1取消后的总空置天数,两个取消日期,97+279=376
T_D_V_w_cancel=未取消的总空置天数,只需求上一个结束日期与下一个开始日期之差的总和
Lst_END_DATE_to_today=从最后一个结束日期到今天的天数。首先创建了新的列,用于可能的简单验证解决方案:
today = pd.to_datetime('now').floor('d')
m = df['CANCELLED_DATE'].isna()
df['D_from_C_to_first_S_D'] = df['START_DATE'].sub(df['CONSTRUCTION_DATE']).dt.days
df['T_D_V_aft_c'] = df.groupby('ID')['START_DATE'].shift(-1).sub(df['CANCELLED_DATE']).dt.days
df['T_D_V_w_cancel'] = df.groupby('ID')['START_DATE'].shift(-1).sub(df.loc[m, 'END_DATE']).dt.days
df['N_of_cancel'] = np.where(m, 0, 1)
s = df['END_DATE'].rsub(today).dt.days
df['Lst_END_DATE_to_today'] = s.mask(s.lt(0), 'After_today')
然后在NaN的自定义函数中按first、last和sum进行聚合,而不是0:
在T_D_V_u aft_c中97号计数如何?@jezrael,ID=1,其第一个取消日期=2017-05-22,从该日期到下一个开始日期2017-08-27的天数,对于T_D_V_w_取消,仅计数为正差异?因为我参加了第一组a-29,-183-214@jezrael我们应该忽略取消日期的行。只考虑行,我们没有取消的数据容易回答,请检查是否像你需要的工作。
print (df)
ID CONSTRUCTION_DATE START_DATE END_DATE CANCELLED_DATE
0 1 2016-02-06 2016-02-26 2017-02-26 NaT
1 1 2016-02-06 2017-03-27 2018-02-26 2017-05-22
2 1 2016-02-06 2017-08-27 2019-02-26 2017-10-21
3 1 2016-02-06 2018-07-27 2021-02-26 NaT
4 2 2016-05-06 2017-03-27 2018-02-26 NaT
5 2 2016-05-06 2018-08-27 2019-02-26 NaT
ID CONSTRUCTION_DATE START_DATE END_DATE CANCELLED_DATE \
0 1 2016-02-06 2016-02-26 2017-02-26 NaT
1 1 2016-02-06 2017-03-27 2018-02-26 2017-05-22
2 1 2016-02-06 2017-08-27 2019-02-26 2017-10-21
3 1 2016-02-06 2018-07-27 2021-02-26 NaT
4 2 2016-05-06 2017-03-27 2018-02-26 NaT
5 2 2016-05-06 2018-08-27 2019-02-26 NaT
D_from_C_to_first_S_D T_D_V_aft_c T_D_V_w_cancel N_of_cancel \
0 20 NaN 29.0 0
1 415 97.0 NaN 1
2 568 279.0 NaN 1
3 902 NaN NaN 0
4 325 NaN 182.0 0
5 843 NaN NaN 0
Lst_END_DATE_to_today
0 1089
1 724
2 359
3 After_today
4 724
5 359
f = lambda x: x.sum(min_count=1)
df1 = df.groupby('ID').agg(D_from_C_to_first_S_D=('D_from_C_to_first_S_D','first'),
T_D_V_aft_c=('T_D_V_aft_c',f),
T_D_V_w_cancel=('T_D_V_w_cancel',f),
N_of_cancel=('N_of_cancel',f),
Lst_END_DATE_to_today=('Lst_END_DATE_to_today','last'),
).reset_index()
print (df1)
ID D_from_C_to_first_S_D T_D_V_aft_c T_D_V_w_cancel N_of_cancel \
0 1 20 376.0 29.0 2
1 2 325 NaN 182.0 0
Lst_END_DATE_to_today
0 After_today
1 359