将Pandas日期转SAS格式并拼接ID生成DateID的优化方案咨询
问题:Pandas日期转SAS日期格式并拼接ID生成DateID
需求说明
需要将Pandas中的日期转换为SAS使用的日期格式,再与ID拼接生成新字段DateID,具体转换要求如下:
原始数据集
ID date 101 20-01-01 102 21-01-01 103 22-01-01
目标数据集
ID DateID date 101 10114995 20-01-01 102 10214996 21-01-01 103 10314997 22-01-01
当前实现问题
我写了逐行处理的函数:
import math import pandas as pd def SASdate(datein): return str(math.trunc(pd.to_timedelta(pd.to_datetime(datein) - pd.to_datetime('1960-1-1'), unit='D') / pd.Timedelta(days=1)))
但遇到两个问题:
- 处理大规模数据集时耗时极长,因为是逐行处理;
- 拼接ID和SAS日期时结果不符合预期,执行代码:
str(df['ID']) + df['date'].apply([SASdate])
得到的输出是:
SASdate 0 0 101\n1 102\n2 103\nName: ID, dtype:... 1 0 101\n1 102\n2 103\nName: ID, dtype:... 2 0 101\n1 102\n2 103\nName: ID, dtype:...
希望找到更高效的方法解决这两个问题。
示例数据集生成代码:
df = pd.DataFrame({'ID': [101,102,103], 'date': ['20-01-01', '21-01-01', '22-01-01'] })
解决方案
1. 向量化转换SAS日期,大幅提升效率
SAS日期本质是从1960-01-01开始的天数,直接用Pandas向量化操作计算,避免逐行apply的性能损耗:
# 将date列转为datetime类型(指定格式解析更高效) df['date_dt'] = pd.to_datetime(df['date'], format='%y-%m-%d') # 直接计算日期差的天数,得到SAS日期数值 df['sas_date_num'] = (df['date_dt'] - pd.to_datetime('1960-01-01')).dt.days
2. 正确拼接ID和SAS日期生成DateID
要保证是元素级别的拼接,直接将两列转为字符串后相加即可,不要用str(df['ID'])(这会把整个Series转成单个字符串):
df['DateID'] = df['ID'].astype(str) + df['sas_date_num'].astype(str)
完整代码
import pandas as pd # 生成示例数据 df = pd.DataFrame({'ID': [101,102,103], 'date': ['20-01-01', '21-01-01', '22-01-01'] }) # 转换日期并计算SAS日期 df['date_dt'] = pd.to_datetime(df['date'], format='%y-%m-%d') df['sas_date_num'] = (df['date_dt'] - pd.to_datetime('1960-01-01')).dt.days # 生成DateID df['DateID'] = df['ID'].astype(str) + df['sas_date_num'].astype(str) # 整理列顺序(可选) df = df[['ID', 'DateID', 'date']] print(df)
输出结果:
ID DateID date 0 101 10114995 20-01-01 1 102 10214996 21-01-01 2 103 10314997 22-01-01
关键优化点
- 用向量化操作替代逐行循环,性能提升几个数量级,适合处理大规模数据;
- 元素级拼接时,确保操作对象是Series的每个元素,而非整个Series的字符串形式。
内容的提问来源于stack exchange,提问作者TDeramus
相关产品推荐
相关产品推荐

