验证列是否在数据框中逐行添加日

2024-06-25 23:08:25 发布

您现在位置:Python中文网/ 问答频道 /正文

我以以下数据帧为例(已按PERSON_NUMBER排序):

                Date_From     Date_To PROPOSAL_REASON
PERSON_NUMBER                                        
3720081000     2008-01-04  2009-12-07           MEINC
3720081000     2018-07-01  2019-03-31           MEINC
3720081000     2019-04-01  2019-10-31           MEINC
3720081018     2018-07-01  2019-03-31           MEINC
3720081018     2019-04-01  2019-10-31           MEINC
3720081077     2018-07-01  2019-03-31           MEINC
3720081111     2019-04-01  2019-10-31           MEINC
3720081211     2018-07-01  2019-03-31           MEINC
3720081211     2019-06-01  2019-10-31           MEINC

我需要验证,每个员工(每个员工可以有一个或多个记录)如果每行,第一条记录+1天的Date_To应该是第二条记录的Date_From,这意味着创建记录的天数应该没有间隔

对于有这种差距的员工,我想筛选他们并将他们保存在另一个数据框中

因此,例如,从give dataframe,我希望下面的输出使用此信息创建一个列(记录的第一行总是OK):

                Date_From     Date_To     CHECK_CONDITION
PERSON_NUMBER                                        
3720081000     2008-01-04  2009-12-07           OK
3720081000     2018-07-01  2019-03-31           WARNING
3720081000     2019-04-01  2019-10-31           OK
3720081018     2018-07-01  2019-03-31           OK
3720081018     2019-04-01  2019-10-31           OK
3720081077     2018-07-01  2019-03-31           OK
3720081111     2019-04-01  2019-10-31           OK
3720081211     2018-07-01  2019-03-31           OK
3720081211     2019-06-01  2019-10-31           WARNING

因此,正如您所看到的,WARNING记录中的Date_From值不是前一个Date_To值+1天


Tags: to数据fromnumberdate排序记录员工
2条回答

您可以尝试以下方法:

df['Date_From'] = pd.to_datetime(df['Date_From'])
df['Date_To'] = pd.to_datetime(df['Date_To'])
df['CHECK_CONDITION'] = (df['Date_From'] - df['Date_To'].shift()).dt.days != 1
print(df)

   PERSON_NUMBER  Date_From    Date_To PROPOSAL_REASON  CHECK_CONDITION
0     3720081000 2008-01-04 2009-12-07           MEINC             True
1     3720081000 2018-07-01 2019-03-31           MEINC             True
2     3720081000 2019-04-01 2019-10-31           MEINC            False
3     3720081018 2018-07-01 2019-03-31           MEINC             True
4     3720081018 2019-04-01 2019-10-31           MEINC            False
5     3720081077 2018-07-01 2019-03-31           MEINC             True
6     3720081111 2019-04-01 2019-10-31           MEINC            False
7     3720081211 2018-07-01 2019-03-31           MEINC             True
8     3720081211 2019-06-01 2019-10-31           MEINC             True

使用:

# STEP 1
df['Date_To'] = pd.to_datetime(df['Date_To'])
df['Date_From'] = pd.to_datetime(df['Date_From'])

# STEP 2
df['count'] = np.arange(df.shape[0])

# STEP 3
m1 = df['Date_From'].sub(df['Date_To'].shift()).dt.days.eq(1)

# STEP 4
m2 = df['count'].eq(df.groupby(level=0)['count'].transform('first'))

# STEP 5
df1 = df.assign(CHECK_CONDITION=np.where(m1 | m2, 'OK', 'WARNING')).drop('count', 1)

说明:

步骤1:使用^{}转换Date_To&Date_From列转换为时间序列

步骤2:使用np.arangedf中创建一个临时列count,作为datframe中行的唯一计数器,这有助于跟踪边界条件,这有助于区分排序数据帧中的下一个雇员和上一个雇员

# df
               Date_From    Date_To PROPOSAL_REASON  count
PERSON_NUMBER                                             
3720081000    2008-01-04 2009-12-07           MEINC      0
3720081000    2018-07-01 2019-03-31           MEINC      1
3720081000    2019-04-01 2019-10-31           MEINC      2
3720081018    2018-07-01 2019-03-31           MEINC      3
3720081018    2019-04-01 2019-10-31           MEINC      4
3720081077    2018-07-01 2019-03-31           MEINC      5
3720081111    2019-04-01 2019-10-31           MEINC      6
3720081211    2018-07-01 2019-03-31           MEINC      7
3720081211    2019-06-01 2019-10-31           MEINC      8

步骤3:创建一个布尔掩码m1,从移位的“Date_To”列中减去“Date_From”,然后使用^{}获得两列之间的天数,然后使用^{}创建一个布尔掩码,其中truthy值对应于总天数等于1的条件

# m1
PERSON_NUMBER
3720081000    False
3720081000    False
3720081000     True
3720081018    False
3720081018     True
3720081077    False
3720081111     True
3720081211    False
3720081211    False
dtype: bool

步骤4:使用Series.eqlevel=0上的^{}创建布尔掩码m2,其中truthy值对应于员工id的边界条件

# m2
PERSON_NUMBER
3720081000     True
3720081000    False
3720081000    False
3720081018     True
3720081018    False
3720081077     True
3720081111     True
3720081211     True
3720081211    False
Name: count, dtype: bool

步骤5:使用^{}根据条件m1 | m2OKWARNING中选择标量值:

# df1 (RESULT)
               Date_From    Date_To PROPOSAL_REASON CHECK_CONDITION
PERSON_NUMBER                                                      
3720081000    2008-01-04 2009-12-07           MEINC              OK
3720081000    2018-07-01 2019-03-31           MEINC         WARNING
3720081000    2019-04-01 2019-10-31           MEINC              OK
3720081018    2018-07-01 2019-03-31           MEINC              OK
3720081018    2019-04-01 2019-10-31           MEINC              OK
3720081077    2018-07-01 2019-03-31           MEINC              OK
3720081111    2019-04-01 2019-10-31           MEINC              OK
3720081211    2018-07-01 2019-03-31           MEINC              OK
3720081211    2019-06-01 2019-10-31           MEINC         WARNING

相关问题 更多 >