Pandas:计算日期列之间不包括周末的天数

cdmah0mi  于 2023-03-11  发布在  其他
关注(0)|答案(1)|浏览(132)

开始的 Dataframe :

df = pd.DataFrame({

    # some ways to create random data
    'User Story Id':np.random.choice( ['US111111','US111112','US111113','US222221','US222222','US222223'], 6,replace=False),
    'Feature Id':np.random.choice( ['F999999','F888888'], 6),
    'Sprint Label':np.random.choice( ['ABC 23.1.1'], 6),
    'Team name':np.random.choice( ['panda','python','shark'], 6),

    # a date range and set of random dates
    'story_being_groomed_ts':pd.date_range('1/10/2023  8:07:21 AM', periods=6, freq='D'),
    'story_in_progress_ts':np.random.choice( pd.date_range('1/10/2023  8:07:21 AM', periods=10,
                          freq='D'), 6, replace=False),
    'story_complete_ts':np.random.choice( pd.date_range('1/20/2023  8:07:21 AM', periods=10,
                          freq='D'), 6, replace=False),
    'story_accepted_ts':np.random.choice( pd.date_range('1/30/2023  8:07:21 AM', periods=10,
                          freq='D'), 6, replace=False),
    'story_release_to_prod_ts':np.random.choice( pd.date_range('2/10/2023  8:07:21 AM', periods=10,
                          freq='D'), 6, replace=False)
    })

我想再添加三列:
'交付周期_1':计算“故事正在进行中”和“故事正在整理”之间的工作日
'交付周期_2':计算“故事已接受"和”故事进行中“之间的工作日
“提前期3”:计算“story_release_to_prod_ts”和“story_accepted_ts”之间的工作日
每个用户情景ID都有一组日期-时间戳列。对于每个用户情景ID,我希望按上述方法计算交付周期:
要使解决方案正常工作,需要满足的关键行条件如下。

  • 从提前期计算中排除周末
  • 如果对于Lead_time_3计算,“story_release_to_prod_ts”为空(意味着接受故事但不发布到生产),则Lead_time_3计算应为“空”
  • 如果对于Lead_time_2计算,“story_accepted_ts”为空(意味着故事正在进行中,但未被产品负责人接受),则Lead_time_2计算应为“blank”
  • 如果对于Lead_time_1计算,“story_in_progress_ts”为空(意味着开发人员正在整理故事,但未在进行中),则Lead_time_1计算应为“空”
  • 提前期_1|提前期_2|如果故事在“story_in_progress_ts”列下没有有效的日期时间戳,则Lead_time_3计算应为空。

我的预期结果:

User Story Id | Feature Id | Sprint Label | Team name | story_being_groomed_ts | story_in_progress_ts | story_complete_ts | story_accepted_ts | story_release_to_prod_ts | Lead Time 1 |Lead Time 2 | Lead Time 3 |

我尝试使用下面的方法构建日期时间差列。

df[['story_being_groomed_ts','story_in_progress_ts']] = df[['story_being_groomed_ts','story_in_progress_ts']].apply(pd.to_datetime) #if conversion required
df['Lead Time'] = (df['story_in_progress_ts'] - df['story_being_groomed_ts']).dt.days
bf1o4zei

bf1o4zei1#

可以按行使用pd.apply,并生成所需的3列,还可以对列的子集使用dropna,以确保所有非日期值都将被删除。
我使用了您建议的数据,但我在其中插入了一个空值,以检查它是否能正常工作。

df.iloc[3,5] = ''

df['lead_time_1'] = df[['story_being_groomed_ts', 'story_in_progress_ts']].dropna().apply(lambda x: pd.date_range(x[0], x[1], freq='B').shape[0],
                                                                                                                       axis=1)

df['lead_time_2'] = df[['story_in_progress_ts', 'story_accepted_ts']].dropna().apply(lambda x: pd.date_range(x[0], x[1], freq='B').shape[0],
                                                                                                                       axis=1)

df['lead_time_3'] = df[['story_accepted_ts', 'story_release_to_prod_ts']].dropna().apply(lambda x: pd.date_range(x[0], x[1], freq='B').shape[0],
                                                                                                                       axis=1)

>>> df.fillna('')[['lead_time_1', 'lead_time_2', 'lead_time_3']] 
# only printing part of the df otherwise is messy to paste here

  lead_time_1 lead_time_2  lead_time_3
0         1.0        22.0            8
1         1.0        16.0            8
2         2.0        14.0            7
3                                   12
4         2.0        15.0            6
5         1.0        15.0            7

相关问题