按datetime64[ns]类型列排序Pandas DataFrame未达预期的原因及修正方案
日期解析错误导致排序异常的问题排查与解决
问题原因
你遇到的核心问题是pandas自动解析日期时混淆了日和月的顺序。虽然df.info()显示Data列是datetime64[ns]类型,但pandas默认的日期解析逻辑会优先尝试mm/dd/yyyy(美式日期)格式,而你的数据集实际采用的是dd/mm/yyyy(欧式日期)格式。
当日期中的“日”部分小于等于12时,pandas会误把它当成月份:比如12/01/2021会被解析成2021-01-12(1月12日),但你实际想要的是2021-12-01(12月1日)。而像01/09/2021这类日期,因为“日”是01(小于12)但“月”是09(超过12),pandas会自动切换成dd/mm/yyyy格式解析,结果就正确——这就是为什么部分日期显示正常、部分异常的原因。
解决方案
要解决这个问题,我们需要强制指定日期解析的格式,让pandas明确按照dd/mm/yyyy来解析Data列,同时保持datetime64[ns]类型不变。这里有两种可靠的实现方法:
方法1:在read_excel中自定义日期解析器
通过date_parser参数传入自定义函数,明确指定日期格式:
import pandas as pd header_list = ['Data', 'Hora', 'Status'] # 自定义日期解析函数,强制按dd/mm/yyyy格式解析 def parse_br_date(date_str): return pd.to_datetime(date_str, format='%d/%m/%Y') # 读取Excel时使用自定义解析器 df = pd.read_excel( r'C:\Users\KMBGSI\Downloads\Historico de Alertas.xlsx', sheet_name='Compilado', header=None, names=header_list, index_col=None, parse_dates=[0], date_parser=parse_br_date ) # 此时再排序就会得到正确结果 df.sort_values(by=['Data'], inplace=True) df.head()
方法2:先读取为文本,再转换为日期
如果第一种方法遇到格式兼容问题,可以先把Data列读取为字符串,再用pd.to_datetime指定格式转换:
import pandas as pd header_list = ['Data', 'Hora', 'Status'] # 先不解析日期,强制按字符串读取Data列 df = pd.read_excel( r'C:\Users\KMBGSI\Downloads\Historico de Alertas.xlsx', sheet_name='Compilado', header=None, names=header_list, index_col=None, dtype={'Data': str} ) # 转换为datetime类型,明确指定dd/mm/yyyy格式 df['Data'] = pd.to_datetime(df['Data'], format='%d/%m/%Y') # 执行排序操作 df.sort_values(by=['Data'], inplace=True) df.head()
验证方法
修改后可以用以下代码确认日期解析正确:
# 检查Data列的数据类型和前几条数据 print(df.info()) print(df['Data'].head())
你会看到所有日期都被正确解析为datetime64[ns]类型,排序后的顺序完全符合预期。
内容的提问来源于stack exchange,提问作者rdgui1991
相关产品推荐
相关产品推荐

