Pandas多列排序问题:字符串日期排序失效及需求实现
解决日期排序问题及后续Excel导出步骤
1. 日期排序异常的原因
你将date列转换为datetime类型后,立刻用strftime转成了dd/mm/yyyy格式的字符串。字符串排序是按字符顺序逐个比较,而非日期的时间逻辑——比如字符串"01/06/1968"会被认为比"29/01/2005"小(因为第一个字符'0' < '2'),但实际后者的日期更早,这就导致排序结果不符合预期。
另外,转换datetime时没加dayfirst=True,Pandas会默认按mm/dd/yyyy解析你的日期,这会导致部分日期解析错误(比如"01/06/1968"会被当成1月6日,而非你实际想要的6月1日),这也是潜在问题。
2. 修复排序的两种方法
方法一:先排序,再转字符串格式
这种方法最简单,先利用datetime类型的时间逻辑排序,再转成你需要的字符串格式:
import pandas as pd df = pd.DataFrame( { "id": [9733, 9733, 9733, 9733, 9733, 9733, 9733, 9733, 2949, 2949, 2949, 2949, 2949, 2949, 2949, 9765, 9765, 9765, 9765, 9765, 9765], "date": ["01/05/2008", "01/06/1968", "01/11/2010", "01/12/2016", "09/03/2011", "09/05/1975", "28/04/2011", "29/01/2005", "08/07/1974", "09/03/2021", "10/03/2021", "18/09/1986", "20/07/2021", "23/09/2017", "26/06/2020", "01/04/1963", "01/08/2012", "02/08/2012", "25/06/2021", "30/11/2020", "31/03/1986",], "status": ["S", "A", "P", "C", "S", "D", "P", "P", "A", "P", "S", "D", "P", "P", "S", "A", "S", "P", "P", "S", "P"], } ) # 转换为datetime,务必加dayfirst=True,匹配你的dd/mm/yyyy格式 df['date'] = pd.to_datetime(df['date'], dayfirst=True) # 按id升序、日期升序排序 df.sort_values(by=['id', 'date'], ascending=[True, True], inplace=True) # 转成需要的字符串格式 df['date'] = df['date'].dt.strftime('%d/%m/%Y')
方法二:保留datetime列用于排序,单独生成显示字符串
如果需要保留原始日期字符串的同时排序,可以新增一个datetime列:
import pandas as pd df = pd.DataFrame( { "id": [9733, 9733, 9733, 9733, 9733, 9733, 9733, 9733, 2949, 2949, 2949, 2949, 2949, 2949, 2949, 9765, 9765, 9765, 9765, 9765, 9765], "date": ["01/05/2008", "01/06/1968", "01/11/2010", "01/12/2016", "09/03/2011", "09/05/1975", "28/04/2011", "29/01/2005", "08/07/1974", "09/03/2021", "10/03/2021", "18/09/1986", "20/07/2021", "23/09/2017", "26/06/2020", "01/04/1963", "01/08/2012", "02/08/2012", "25/06/2021", "30/11/2020", "31/03/1986",], "status": ["S", "A", "P", "C", "S", "D", "P", "P", "A", "P", "S", "D", "P", "P", "S", "A", "S", "P", "P", "S", "P"], } ) # 新增datetime列用于排序 df['date_dt'] = pd.to_datetime(df['date'], dayfirst=True) # 按id和datetime列排序 df.sort_values(by=['id', 'date_dt'], ascending=[True, True], inplace=True) # 更新date列为指定格式的字符串 df['date'] = df['date_dt'].dt.strftime('%d/%m/%Y') # 不需要datetime列的话可以删除 df.drop('date_dt', axis=1, inplace=True)
3. 导出到Excel的不同工作表
排序完成后,用pd.ExcelWriter可以将不同status的数据写入同一个Excel文件的不同工作表:
# 创建Excel写入对象,指定输出文件名 with pd.ExcelWriter('sorted_output.xlsx') as writer: # 筛选status为P的数据,写入名为"P"的工作表 df[df['status'] == 'P'].to_excel(writer, sheet_name='P', index=False) # 筛选status为A的数据,写入名为"A"的工作表 df[df['status'] == 'A'].to_excel(writer, sheet_name='A', index=False) # 筛选status为D的数据,写入名为"D"的工作表 df[df['status'] == 'D'].to_excel(writer, sheet_name='D', index=False)
内容的提问来源于stack exchange,提问作者R41nMak3R
相关产品推荐
相关产品推荐

