按自定义列表对Pandas DataFrame指定列排序报错求助
解决Pandas按自定义列表排序DataFrame列的问题
你的代码核心错误是给df4的Invoice列赋值时,错误使用了原始df的Invoice列——df4是透视表重置索引后的结果,和原始df的行数、数据对应关系不一致,导致赋值错误。另外,自定义sorter列表未包含原始数据中的soccer值,设置分类后这些值会被转为NaN,排序时默认排在末尾。
修正后的完整代码
import pandas as pd import numpy as np df = pd.DataFrame({ 'JDate':["2022-01-31","2022-12-05","2023-11-10","2023-12-03","2024-01-16","2024-01-06","2011-01-04"], 'Code':[None,'John Johnson',np.nan,'John Smith','Mary Williams','ted bundy','George Lucas'], 'Unit Price':[np.nan,200,None,56,75,65,60], 'Quantity':[1500, 140000, 1400000, 455, 648, 759,1000], 'Amount':[100, 10000, 100000, 5, 48, 59,449], 'Invoice':['soccer','basketball','baseball','football','baseball','ice hockey','football'], 'energy':[100.,100,100,54,98,3,45], 'Category':['alpha','bravo','kappa','alpha','bravo','bravo','kappa'] }) df["JDate"] = pd.to_datetime(df["JDate"]) df["JYearMonth"] = df['JDate'].dt.to_period('M') index_to_use = ['Category','Code','Invoice','Unit Price'] values_to_use = ['Amount'] columns_to_use = ['JYearMonth'] df2 = df.pivot_table(index=index_to_use, values=values_to_use, columns=columns_to_use) df4 = df2['Amount'].reset_index() # 自定义排序列表 sorter=['football','ice hockey','basketball','baseball'] # 修正:对df4自身的Invoice列设置分类,指定排序顺序 df4['Invoice'] = pd.Categorical(df4['Invoice'], categories=sorter, ordered=True) # 按自定义顺序排序,将不在sorter中的值放在末尾 df4.sort_values(['Invoice'], inplace=True, na_position='last') df3 = df2.xs('alpha',level='Category') df3 = df3.reset_index() writer= pd.ExcelWriter( "t2test11.xlsx", engine='xlsxwriter' ) df.to_excel(writer,sheet_name="t2",index=True) df2.to_excel(writer,sheet_name="t2test",index=True) df4.to_excel(writer,sheet_name="t2testFixHeader",index=True) df3.to_excel(writer,sheet_name="t2filter",index=True) writer.close()
关键修改说明
- 修正赋值对象:直接操作df4自身的Invoice列,避免原始数据和透视后数据的不匹配问题。
- 明确分类规则:用
pd.Categorical一次性指定分类列表和排序顺序,逻辑更清晰。 - 处理未定义值:通过
na_position='last'将不在自定义列表中的soccer放在排序结果末尾;如果需要将soccer纳入自定义排序,只需把它添加到sorter列表的对应位置即可。
内容的提问来源于stack exchange,提问作者Alhpa Delta
相关产品推荐
相关产品推荐

