乐于分享
好东西不私藏

Excel自定义排序太麻烦?Python这2种方法教你轻松搞定

Excel自定义排序太麻烦?Python这2种方法教你轻松搞定

最近收到小伙伴一个关于自定义排序的问题。
Excel工作表A列是一组公司的名称,要求C、D、E列的数据根据第一列的顺序排序。这是工作表的第一列:
这是要排序的数据源:
做过数据统计的朋友都遇到过按数字、字母、首拼或笔画的问题,可是对于类似企业名单、客户信息、地理位置等,不能按数字、字母等来排序,只能按固定的序列进行排序。手动一个一个拖拽显然不是我们想要做的,增加辅助列又显得有点繁琐。那么有没有快速实现的方法?
今天就把用Python解决的方法分享给大家,或许让你能少走些弯路。先来看代码:
import pandas as pdxlsx_path = r'D:\数据源.xlsx'# 获取自定义列df_list = pd.read_excel(xlsx_path,usecols=[0]).dropna()px_list = df_list["名称"].tolist()# 获取需要排序的数据df_data = pd.read_excel(xlsx_path,usecols=[2,3,4],dtype=str).dropna()# 需要排序的所有值px_other = [x for x in df_data["企业名称"].unique() if x not in px_list]px_list = px_list + px_other# 排序df_data["企业名称"] = pd.Categorical(df_data["企业名称"],categories=px_list,ordered=True)df_new = df_data.sort_values("企业名称")# 保存df_new.to_excel(r'D:\数据源_排序后.xlsx',index=False)
这个方法借助pandas中的Categorical()方法直接给数据绑定自定义顺序。
第5行是获取A列的公司名称并转换为列表。
第9行是获取C列有但A列没有的公司名称。
第10行是将两者组合成一个新的列表,其中前半部分是需要排序的公司名称,后半部分是没有指定排序的名称。
第12行是使用Categorical()将数据转换为有序分类变量,实现自定义排序。在这里需要补充说明一下,如果categories的值仅包括A列有的公司名称,C列有A列没有的公司将被替换为NaN。
第13行按企业名称列排序。
第15行保存Excel表格到指定目录。
这段代码最大的特点是容错率高,哪怕数据有空白、重复值,也都能正常处理。
其实,还有一种解决的思路,类似于添加辅助列。也就是说给每个需要自定义排序的公司名称分配专属序号,再用排序键实现自定义排序,代码更精简。
import pandas as pdxlsx_path = r'D:\数据源.xlsx'# 获取自定义列df_list = pd.read_excel(xlsx_path,usecols=[0]).dropna()px_list = df_list["名称"].tolist()# 获取需要排序的数据df_data = pd.read_excel(xlsx_path,usecols=[2,3,4],dtype=str).dropna()order_map = {name : i for i,name in enumerate(px_list)}# 定义排序键def sort_key(x):    return x.map(order_map).fillna(len(px_list))# 排序df_new = df_data.sort_values(by='企业名称', key=sort_key)df_new.to_excel(r'D:\数据源_排序后1.xlsx',index=False)
上面的代码是通过构建映射字典,定义排序键函数,直接通过sort_values按自定义键排序,企业名称不在字典内的数据就赋值一个较大的值,统一排在最后。
第8行通过map方法枚举px_list构建映射字典。
第9-11行通过自定义函数来定义排序的键,对企业名称未在映射字典内的值统一赋值最大序号。
第13行按自定义键进行排序。
这段代码排序的效率更高,后续拓展性更强,适合多列自定义排序、复杂排序规则。
运行代码后,效果如下图所示:
好了,今天的分享就到这里,如果你觉得有用,记着点赞并转发给身边还在加班做报表的同事吧!