如何对Pandas DataFrame的字母数字列名进行自然排序?
Pandas DataFrame列名的自然排序(类似R的mixedsort)
你碰到的问题是Pandas默认的列排序(df.sort_index(axis=1)或sorted(df.columns))用的是字典序,会把a10这类带数字的列名排在a2前面,完全不是想要的自然排序效果。要实现类似R语言mixedsort/mixedorder的通用排序,不管列名是纯字母、字母数字混合还是带特殊字符,都能正确排序,我们可以自定义排序规则。
核心思路
把列名拆分为「非数字段」和「数字段」,将数字段转换成整数后再参与排序,这样数字会按数值大小比较,而非字符串字典序。
完整实现代码
import pandas as pd import re # 示例数据 data = { 'year': [2014, 2018, 2020, 2017], 'a1': ["toyota", "honda", "hyndai", "nissan"], 'a10': ["corolla", "civic", "accent", "sentra"], 'b10': ["toyota", "honda", "hyndai", "nissan"], 'a%': ["corolla", "civic", "accent", "sentra"], 'a2': ["toyota", "honda", "hyndai", "nissan"], 'b': ["corolla", "civic", "accent", "sentra"], 'b2': ["corolla", "civic", "accent", "sentra"] } df = pd.DataFrame(data) # 定义自然排序的key函数 def natural_sort_key(s): # 拆分字符串为非数字和数字部分,数字转整数,字符串统一小写(如需区分大小写可去掉.lower()) parts = re.split(r'(\d+)', s) return [int(part) if part.isdigit() else part.lower() for part in parts] # 按自然排序规则重新排列列 sorted_columns = sorted(df.columns, key=natural_sort_key) df_sorted = df.reindex(sorted_columns, axis=1) # 输出排序后的列名 print(df_sorted.columns)
运行结果
排序后的列顺序为:Index(['a%', 'a1', 'a2', 'a10', 'b', 'b2', 'b10', 'year'], dtype='object')
规则说明
- 带特殊字符的列(如
a%)按字符串本身排序 - 字母数字混合列(如
a1/a2/a10)先按字母部分排序,再按数字的数值大小排序 - 纯字母、纯数字列均能正确适配
- 函数中
part.lower()用于实现不区分大小写排序,若需要严格区分大小写,删除该部分即可
内容的提问来源于stack exchange,提问作者Mathica
相关产品推荐
相关产品推荐

