Python Pandas日期处理优化:动态变量与多条件判断需求
解决方案
问题点梳理
- 你修改后的函数无法获取
Year和Month:因为apply的lambda只传递了日期列的单个值x,函数内部无法访问外部的Year/Month变量;如果Year/Month是DataFrame的列,直接字符串拼接会因Series类型报错。 - 缺少
Policy列的判断逻辑:需要先判断Policy是否为X,再决定是否执行日期修正。
高效实现方案(推荐用向量化操作,比apply效率高很多)
第一步:生成动态基准日期
先将Year和Month转换为标准日期格式,注意月份要补为两位(如9月转为09):
# 假设Year和Month是外部数值变量,例如Year=2023、Month=6 benchmark_date = pd.to_datetime(f"{Year:04d}-{Month:02d}-01") # 如果Year和Month是DataFrame的列(比如file中包含Year、Month列),写法如下: benchmark_date = pd.to_datetime( file['Year'].astype(str).str.zfill(4) + '-' + file['Month'].astype(str).str.zfill(2) + '-01' )
第二步:结合Policy条件处理日期
用numpy.where实现批量判断,无需循环或apply,执行效率更高:
import pandas as pd import numpy as np # 先将原日期列转为datetime类型,避免重复转换浪费资源 file['CASH RECIEVED DATE'] = pd.to_datetime(file['CASH RECIEVED DATE']) # 生成基准日期(以外部变量为例) Year = 2019 Month = 9 benchmark_date = pd.to_datetime(f"{Year:04d}-{Month:02d}-01") # 核心逻辑:Policy为X时取原日期与基准日期的较大值,否则直接用原日期 file['Cash Received Date'] = np.where( file['Policy'] == 'X', file['CASH RECIEVED DATE'].clip(lower=benchmark_date), # clip方法直接设置日期下限,比if-else更简洁 file['CASH RECIEVED DATE'] )
若坚持使用apply(不推荐,大数据量下速度慢)
需将Policy和基准日期一起传入函数,修改方式如下:
def compare_date(row, benchmark_date): if row['Policy'] == 'X': return max(pd.to_datetime(row['CASH RECIEVED DATE']), benchmark_date) else: return pd.to_datetime(row['CASH RECIEVED DATE']) # 生成基准日期 benchmark_date = pd.to_datetime(f"{Year:04d}-{Month:02d}-01") # apply时按行传递参数 file['Cash Received Date'] = file.apply( lambda row: compare_date(row, benchmark_date), axis=1 )
测试效果示例
假设输入数据为:
file = pd.DataFrame({ 'CASH RECIEVED DATE': ['2018-07-23', '2019-09-26', '2017-05-02', '2024-01-15'], 'Policy': ['X', 'Y', 'X', 'X'] }) Year = 2019 Month = 9
执行后输出结果:
CASH RECIEVED DATE Policy Cash Received Date 0 2018-07-23 X 2019-09-01 1 2019-09-26 Y 2019-09-26 2 2017-05-02 X 2019-09-01 3 2024-01-15 X 2024-01-15
内容的提问来源于stack exchange,提问作者rafatomillero
相关产品推荐
相关产品推荐

