如何基于Name列拆分Pandas DataFrame并生成排除周末的日期序列
按姓名生成工作日日期序列的解决方案
原始数据与需求
现有包含name、_leavestartdate、_leaveenddate列的Pandas DataFrame,初始化代码如下:
import pandas as pd df = pd.DataFrame({'name':["Jerry Rice","Pablo Picasso","Ray Ramon"],'_leavestartdate':["2023-12-26","2023-08-15","2023-03-16"],'_leaveenddate':["2023-12-26","2023-08-21","2023-03-17"]})
需求:按name拆分数据,为每个姓名生成_leavestartdate到_leaveenddate之间的所有工作日日期(排除周六、周日),将日期存入新列Date,最终仅保留工作日对应的行。
修正后的完整代码
import pandas as pd # 初始化原始数据 df = pd.DataFrame({ 'name': ["Jerry Rice", "Pablo Picasso", "Ray Ramon"], '_leavestartdate': ["2023-12-26", "2023-08-15", "2023-03-16"], '_leaveenddate': ["2023-12-26", "2023-08-21", "2023-03-17"] }) # 1. 将字符串日期转为datetime类型,确保日期运算正常 df['_leavestartdate'] = pd.to_datetime(df['_leavestartdate']) df['_leaveenddate'] = pd.to_datetime(df['_leaveenddate']) # 2. 定义生成工作日的函数:处理单一行的日期区间 def get_workdays(row): # 生成起止日期之间的所有日期 all_dates = pd.date_range(start=row['_leavestartdate'], end=row['_leaveenddate'], freq='D') # 过滤工作日:weekday()返回0-4对应周一到周五,5、6是周末 work_dates = all_dates[all_dates.weekday() < 5] # 返回当前姓名+工作日的DataFrame片段 return pd.DataFrame({ 'name': [row['name']] * len(work_dates), 'Date': work_dates }) # 3. 遍历每一行生成数据,合并所有结果 final_result = pd.concat([get_workdays(row) for _, row in df.iterrows()], ignore_index=True) # 打印结果 print(final_result)
关键说明
- 日期类型转换:必须先把字符串格式的日期转为
datetime类型,否则无法用pd.date_range生成连续日期序列。 - 工作日过滤逻辑:利用
datetime对象的weekday()方法,0=周一,4=周五,5=周六,6=周日,通过weekday() <5直接筛掉周末。 - 按姓名拆分处理:通过遍历每行数据(每个姓名对应一个日期区间),为每个姓名单独生成工作日序列,再拼接成最终结果,确保姓名和日期一一对应。
运行结果示例
name Date 0 Jerry Rice 2023-12-26 1 Pablo Picasso 2023-08-15 2 Pablo Picasso 2023-08-16 3 Pablo Picasso 2023-08-17 4 Pablo Picasso 2023-08-18 5 Pablo Picasso 2023-08-21 6 Ray Ramon 2023-03-16 7 Ray Ramon 2023-03-17
(注:2023-08-19、2023-08-20为周末,已被自动排除)
内容的提问来源于stack exchange,提问作者PineNuts0
相关产品推荐
相关产品推荐

