Pandas转换'Thursday, March 03, 2019'为%m/%d/%y时报错如何解决?
错误原因
Unconverted Data Remains报错的核心是你传入的日期字符串有部分内容无法匹配你指定的%A, %B %d, %Y格式,常见诱因有两个:
- 系统语言环境不是英文:
%A(星期全称)、%B(月份全称)默认匹配系统本地语言的名称,你的日期是英文拼写,系统语言为中文等非英文环境时会识别失败。 - 日期列存在脏数据:部分值存在多余空格、特殊字符、缩写的星期/月份、格式不统一等问题,无法匹配预设格式。
另外你现有代码的strftime格式和需求不符:你要的输出是3/3/2019(月/日/年),现有代码用的%d/%m/%Y是日/月/年格式,输出会和预期不一致。
解决方法
- 第一步:临时切换时间解析的语言环境为英文,避免语言不匹配问题
import locale import pandas as pd import datetime as dt # Windows系统用下面的设置 locale.setlocale(locale.LC_TIME, 'en_US') # Linux/macOS系统如果上面的报错,换成下面的 # locale.setlocale(locale.LC_TIME, 'en_US.UTF-8')
- 第二步:优先用pandas自带的
to_datetime方法解析,效率远高于自定义apply,还能灵活处理异常
# 先备份原日期列,方便后续排查脏数据 df_['origin_date'] = df_['Date'] # 解析日期,errors='coerce'会把不符合格式的内容转为空值NaT,不会直接抛出错误中断运行 df_['Date'] = pd.to_datetime(df_['Date'], format='%A, %B %d, %Y', errors='coerce') # 转为你需要的月/日/年格式,同时去掉月份、日期前的前置0,实现3/3/2019的效果 df_['Date'] = df_['Date'].dt.strftime('%m/%d/%Y').str.replace(r'^0', '', regex=True).str.replace(r'/0', '/', regex=True)
- 第三步:排查脏数据(可选)
如果解析后出现空值,用下面的代码找出所有解析失败的原始日期,手动处理异常值:
# 输出所有解析失败的原始日期内容 print(df_[df_['Date'].isna()]['origin_date'])
- 如果你需要保留解析失败的原始值,不想转成空值,可以用带异常捕获的自定义函数实现:
def convert_date(x): try: date_val = dt.datetime.strptime(x, '%A, %B %d, %Y') return date_val.strftime('%m/%d/%Y').lstrip('0').replace('/0', '/') except ValueError: # 解析失败直接返回原始值 return x df_['Date'] = df_['Date'].apply(convert_date)
内容的提问来源于stack exchange,提问作者rankinjq
相关产品推荐
相关产品推荐

