国庆上海一行(三)

 

(位置:黄浦区,外滩。时间:中午12点)

在外滩边上,一路逛过来,就到了尾端。末尾入口处有座英雄纪念碑。碑建在江边,底下泛黄的江水缓缓流过,俯看片刻,便出了去。街上行人熙熙攘攘,好不热闹。从外滩到浦东,倒是坐了回海底观光隧道的游览车,单程45¥,只是有点玄幻,也没其他意思,五、十分钟就到了。出了隧道,东方明珠即入眼帘,近处观望,体积确实显得很庞大。观光门票有点贵,况且在学校时也已决定只上金茂大厦一看。仰望片刻,便动身前往金茂,绕了些弯,步行了许久后,终于来到金茂大厦楼下,(http://www.jinmao88.com/ )在那还买了几个纪念品,带回给大家分享。进了主楼,再下一层就是售票厅了,学生票60¥。电梯旁已有一堆人在等候上去。两台每秒运行 9.1 的超高速垂直升降电梯,一次可乘载33位游客,只需45秒钟就可将游客从地下一层直送88层。进了电梯后,扬声器里响起了欢迎……的声音,电梯即刻启动,电梯内壁上有一个显示高度的指示灯。这么快的速度下,在电梯内明显感觉到耳朵在嗡鸣,果然只一小会,便升到了88层。出了电梯,四周已站满了人,向窗下望去,黄浦江两岸景观尽在眼底。眺望远处,看的无边无际。只是白天上去,没见着五彩缤纷的夜景,甚为可惜。放眼远处,继续在四周转了转。在这上海的标志性建筑上,看到的是中国经济腾飞的一个缩影,作为中国最开放的城市之一,这里展现了中国最具代表性的一面。88层中间还可以望下去,下面一环一层,只怕恐高症的人会受不了,我也有点,尽力克服。下楼时,同样感受到这架电梯给我耳朵的好礼,耳膜又嗡了一回。

出了大厦,便掂量着如何去科技馆(http://www.sstm.org.cn/structure/index )。问好路后,乘二号线到达,从外面科技馆看起来也相当漂亮。进去在服务台处寄存了沉重的包裹(四个玻璃制的纪念品,使重量迅速增加,以致后来只得扛在肩上了)。进了售票厅,同样是问‘学生证能不能打折’,对方回答‘你是大学生了吧,大学生不能打折的’,云云。上了二楼检票进去,首先是自然馆,展馆里面的布置使人身临其境,很漂亮,动物、昆虫、树林、小型生态系统、微生物等模型很丰富逼真,令人留恋忘返。只是时间不候人。赶忙奔向下个展馆,全部展馆看下来后,感觉这里涉及了自然、人文、科技等的方方面面,可谓是精彩纷呈,应接不暇。里面更是有很多互动游戏,不过大家参加的积极性都很高,又迫于时间,只玩了那些人烟稀少的游戏。里面有个比大脑集中力的游戏,很想参与,因人太多,又是开放定时,也遗憾而去;另外有一个水柱搞不懂,上面一个水龙头,一个口开着,下面是大容器,盛着一半水不到,水龙头跟容器间形成一个水柱,就这样子,把水龙头顶在空中,晕了。科技馆里面好看耐玩的东西确实非常多,如果时间充裕的话,可以玩上个一整天。匆匆看过,匆匆离开,也算是饱了眼福。楼下一楼有一个蒂森克虏伯(http://www.thyssenkrupp.com.cn/cn/ )的科技周展览,也进去瞧了一下。也正是这么一瞧,有了下面的一段巧遇。门口有个免费照相的,就去照了张。这次在上海,总共就照了三张,两张外滩上,还有一张就是这。说是10分钟后取照,就在里面四处逛了逛,展区挺多,分布随意,但错落有致,每个展台都有一两负责人。这时人已经相当累了,看见一个展台还有椅子空着,就飞身过去坐下,怎一个‘爽’字了得。这里好像是展览材料的,一位年轻女士正在为参观者解说。过后,我见他们离去,便蹭上去资讯,聊了一下这次展览的主题和这家公司的业务,之后就离开了。说来也很巧,这次聊天正好成了下一次的相识。

(待续。。。)

``` merged_data0 = pd.merge(workday, delay_data, on='CHId', how='left') jiean_data= jiean_data[['CHId','UserName','UpdateTime']] jiean_data['UpdateTime'] = pd.to_datetime(jiean_data['UpdateTime']).dt.date merged_data = pd.merge(merged_data0, jiean_data, on='CHId', how='left') # merged_data.to_csv('计算结果0319.csv', index=False, encoding='utf_8_sig') # 处理工期列中的"协商"文本(替换为0) merged_data['工期'] = pd.to_numeric(merged_data['工期'].replace('协商', -999), errors='coerce').fillna(-999) # 处理空值 merged_data['GongQiHuanBan'] = merged_data['GongQiHuanBan'].fillna(0) # 日期格式转换 merged_data['SADate'] = pd.to_datetime(merged_data['SADate']) merged_data['UpdateTime'] = pd.to_datetime(merged_data['UpdateTime']) holidays = [ # 元旦(不调休) '2025-01-01', # 周 # 春节(调休2天) '2025-01-28', '2025-01-29', '2025-01-30', '2025-01-31', '2025-02-01', '2025-02-02', '2025-02-03', '2025-02-04', # 1.28(除夕)-2.4 # 清明节(不调休) '2025-04-04', '2025-04-05', '2025-04-06', # 周五-周日 # 劳动节(调休1天) '2025-05-01', '2025-05-02', '2025-05-03', '2025-05-04', '2025-05-05', # 周四-周一 # 端午节(不调休) '2025-05-31', '2025-06-01', '2025-06-02', # 周六-周一 # 中秋节+国庆节(调休2天) '2025-10-01', '2025-10-02', '2025-10-03', '2025-10-04', '2025-10-05', '2025-10-06', '2025-10-07', '2025-10-08' # 周-下周 ] holiday_dates = pd.to_datetime(holidays) # 新增调休工作日列表(转换为日期格式) workdays_adjustment = [ '2025-01-26', # 周日补春节 '2025-02-08', # 周六补春节 '2025-04-27', # 周日补劳动节 '2025-09-28', # 周日补国庆 '2025-10-11' # 周六补国庆 ] adjustment_dates = pd.to_datetime(workdays_adjustment) # 转换日期格式 def calculate_workdays(start_date, end_date): # 处理未结案情况 end_date = end_date if pd.notnull(end_date) else pd.Timestamp.now() # 生成日期序列 date_range = pd.date_range(start=start_date.normalize(), end=end_date.normalize(), freq='D') # 修改过滤条件(增加调休判断) workdays = [date for date in date_range if ( (date.weekday() < 5) or # 常规工作日 (date in adjustment_dates) # 调休补班日 ) and (date not in holiday_dates) # 排除法定假日 ] return len(workdays) # 计算总工期 merged_data['总工期'] = merged_data['工期'] + merged_data['GongQiHuanBan'] # 计算实际工作日 merged_data['实际工作日'] = merged_data.apply( lambda x: calculate_workdays(x['SADate'], x['UpdateTime']), axis=1 ) # 判断超时 merged_data['是否超时'] = '否' merged_data['超时天数'] = 0 mask = merged_data['实际工作日'] > merged_data['总工期'] merged_data.loc[mask, '是否超时'] = '是' merged_data.loc[mask, '超时天数'] = merged_data['实际工作日'] - merged_data['总工期']```利用节假日判断函数,计算HuanBanDate和HuanBanReDate之间有多少个工作日,HuanBanDate为空值的话,GongQiHuanBan直接填充0,HuanBanDate存在时间,HuanBanReDate为空值,获取程序运行时间到HuanBanReDate,计算到的工作日到GongQiHuanBan的时间
03-21
<think>好的,我现在需要帮助用户修改他们的Python代码,以利用现有的节假日判断函数来计算HuanBanDate和HuanBanReDate之间的工作日数。用户还提到了一些条件,比如处理空值的情况。让我仔细分析他们的代码,然后思考如何实现这些修改。 首先,用户提供的现有代码主要处理工期的计算,包括合并数据、处理文本值、填充空值、日期转换,以及使用calculate_workdays函数来计算实际工作日。现在需要将这个逻辑应用到HuanBanDate和HuanBanReDate字段上,同时处理空值的情况。 用户的需求是:当HuanBanDate为空时,GongQiHuanBan填充0;当HuanBanDate存在但HuanBanReDate为空时,使用当前时间作为结束日期,并计算这两个日期之间的工作日数,结果存入GongQiHuanBan。同时,他们希望利用现有的节假日判断函数来实现这一点。 我需要先理解现有的calculate_workdays函数。这个函数接收开始和结束日期,生成日期范围,然后根据常规工作日、调休补班日和排除法定假日来过滤出有效的工作日。这应该可以直接用于计算HuanBanDate和HuanBanReDate之间的工作日数。 接下来,处理空值的逻辑。根据用户的要求: 1. 如果HuanBanDate为空,GongQiHuanBan设为0。 2. 如果HuanBanDate存在但HuanBanReDate为空,使用当前时间作为结束日期,并计算工作日数。 3. 如果两者都存在,直接计算之间的工作日数。 现有的代码中,GongQiHuanBan列被填充为0,但用户可能需要替换这部分逻辑。原来的代码是: merged_data['GongQiHuanBan'] = merged_data['GongQiHuanBan'].fillna(0) 这可能意味着GongQiHuanBan原本已经有数据,但可能存在空值,所以填充0。但现在用户希望根据HuanBanDate和HuanBanReDate重新计算这个字段的值,所以需要修改这里的处理方式。 接下来,需要确定数据中是否存在HuanBanDate和HuanBanReDate列。假设这些列已经存在于merged_data中,否则可能需要先合并或创建这些列。 然后,应用calculate_workdays函数到这两个日期列。使用apply方法,结合lambda函数,按行处理。对于每一行: - 检查HuanBanDate是否为空:如果是,GongQiHuanBan设为0。 - 如果HuanBanDate存在,但HuanBanReDate为空,则使用pd.Timestamp.now()作为结束日期。 - 否则,使用HuanBanReDate作为结束日期。 需要注意的是,日期列可能需要转换为datetime类型,如果有空值需要处理,比如转换为NaT。此外,如果HuanBanDate存在但HuanBanReDate为空时,需要动态获取当前时间,这可能需要在每次计算时都获取最新时间,或者固定一个时间点,这取决于用户的需求。 然后,应用calculate_workdays函数到这些日期上,得到工作日数,并将其赋值给GongQiHuanBan列。 另外,用户提到原来的代码中GongQiHuanBan被填充为0,这可能与新逻辑冲突。需要确认是否需要完全替换原来的填充逻辑,还是保留其他情况下的填充。根据用户的需求,应该替换原有的填充方式,改为根据日期计算的结果。 现在,将这些步骤转化为代码: 1. 处理HuanBanDate和HuanBanReDate的空值,并转换日期格式。 2. 对于每一行数据,根据条件计算工作日数。 3. 将结果赋值给GongQiHuanBan列。 可能的代码修改: 首先,确保日期列是datetime类型: merged_data['HuanBanDate'] = pd.to_datetime(merged_data['HuanBanDate'], errors='coerce') merged_data['HuanBanReDate'] = pd.to_datetime(merged_data['HuanBanReDate'], errors='coerce') 然后,应用条件逻辑: merged_data['GongQiHuanBan'] = merged_data.apply( lambda row: 0 if pd.isnull(row['HuanBanDate']) else calculate_workdays( row['HuanBanDate'], row['HuanBanReDate'] if pd.notnull(row['HuanBanReDate']) else pd.Timestamp.now() ), axis=1 ) 不过,这里需要注意,当HuanBanReDate为空时,结束日期应该是当前时间。但如果在apply函数中直接使用pd.Timestamp.now(),每次调用都会获取当前时间,可能导致同一批数据中不同行的结束时间不同。如果用户希望所有行的结束时间一致,可能需要预先定义一个变量,比如current_time = pd.Timestamp.now(),然后在lambda中使用这个变量。 此外,需要处理HuanBanDate和HuanBanReDate之间的顺序,确保开始日期早于结束日期,或者在函数中处理这种情况。 最后,可能还需要处理其他异常情况,比如HuanBanDate在未来的情况,但用户没有提到,可能需要默认处理或添加检查。 总结修改步骤: - 转换日期列为datetime类型,处理可能的错误。 - 使用apply和lambda按行应用条件逻辑,计算工作日数。 - 替换原有的填充0的逻辑,使用新的计算结果。 现在,我需要验证这些步骤是否正确,以及是否覆盖了所有用户提到的条件。同时,确保代码不会引入新的错误,例如类型错误或空值处理不当的问题。</think>我将分步骤为您解析代码修改方案,并给出完整实现: 一、基础处理逻辑 ```python # 日期格式转换(处理空值) merged_data['HuanBanDate'] = pd.to_datetime(merged_data['HuanBanDate'], errors='coerce') merged_data['HuanBanReDate'] = pd.to_datetime(merged_data['HuanBanReDate'], errors='coerce') # 获取当前时间作为统一基准时间(避免多次调用now()产生时间差) current_time = pd.Timestamp.now() ``` 二、核心计算函数 ```python def calc_huanban_workdays(row): """计算换班日期区间的工作日""" # 场景1:无换班开始日期 if pd.isnull(row['HuanBanDate']): return 0 # 场景2:有开始日期但无结束日期 end_date = row['HuanBanReDate'] if pd.notnull(row['HuanBanReDate']) else current_time # 场景3:结束日期早于开始日期(异常数据处理) if end_date < row['HuanBanDate']: return 0 # 调用已有的节假日判断函数 return calculate_workdays(row['HuanBanDate'], end_date) ``` 、应用计算逻辑 ```python # 覆盖原填充逻辑,使用动态计算值 merged_data['GongQiHuanBan'] = merged_data.apply(calc_huanban_workdays, axis=1) # 处理异常结果(可选) merged_data['GongQiHuanBan'] = merged_data['GongQiHuanBan'].clip(lower=0) # 确保非负数 ``` 四、验证建议 ```python # 验证特殊场景 print("空值场景验证:") print(merged_data[merged_data['HuanBanDate'].isnull()][['HuanBanDate', 'GongQiHuanBan']].head()) print("\n有开始无结束场景验证:") temp_df = merged_data[merged_data['HuanBanReDate'].isnull() & merged_data['HuanBanDate'].notnull()] print(temp_df[['HuanBanDate', 'HuanBanReDate', 'GongQiHuanBan']].head()) print("\n完整日期场景验证:") print(merged_data[merged_data['HuanBanReDate'].notnull()][['HuanBanDate', 'HuanBanReDate', 'GongQiHuanBan']].head()) ``` 五、扩展优化建议 1. 性能优化方案(大数据量时): ```python # 向量化操作替代apply mask = merged_data['HuanBanDate'].notnull() merged_data['GongQiHuanBan'] = 0 # 处理有开始日期的记录 valid_records = merged_data[mask] merged_data.loc[mask, 'GongQiHuanBan'] = [ calculate_workdays(start, end if pd.notnull(end) else current_time) for start, end in zip(valid_records['HuanBanDate'], valid_records['HuanBanReDate']) ] ``` 2. 时区处理(如需): ```python # 设置时区(以上海时区为例) import pytz current_time = pd.Timestamp.now(tz=pytz.timezone('Asia/Shanghai')) merged_data['HuanBanDate'] = merged_data['HuanBanDate'].dt.tz_localize(pytz.UTC).dt.tz_convert('Asia/Shanghai') ``` 3. 日志记录(关键操作追踪): ```python def calc_huanban_workdays(row): try: # ...原有逻辑... except Exception as e: print(f"计算错误 CHId={row['CHId']}: {str(e)}") return 0 ``` 最终代码执行效果: - 当 `HuanBanDate` 为空时:$GongQiHuanBan = 0$ - 当 `HuanBanDate` 存在但 `HuanBanReDate` 为空时:$GongQiHuanBan = calculate\\_workdays(start=HuanBanDate, end=current\\_time)$ - 当两日期均存在时:$GongQiHuanBan = calculate\\_workdays(HuanBanDate, HuanBanReDate)$ 该方案完整实现了: 1. 空值处理的层条件分支 2. 动态时间基准的统一管理 3. 异常数据的防御性处理 4. 与现有节假日计算逻辑的无缝集成
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值