如何高效对Pandas DataFrame中的字母数字列进行排序
Pandas大数量级DataFrame字母数字分组排序高效方案
问题场景
现有带cell列的Pandas DataFrame,cell值为下划线分隔的5段格式(如cell1_D11_TX_L_90),需求如下:
- 按第1段(如
cell/cell1)和第3段(如TX/TY)的唯一组合分组 - 组内对第2段(如
D1/D11/D1P5)执行字母数字自然排序(常规字符串排序会出现D11排在D3前的问题)
现有循环分组方法在30-50万行数据下运行缓慢,且无法使用natsort库,需更高效的向量化解法。
示例数据
import pandas as pd import numpy as np d = { 'cell': [ 'cell_D1_TX_L_90', 'cell_D11_TX_L_90', 'cell_D14_TX_L_90', 'cell_D4_TX_L_90', 'cell_D3_TX_L_90', 'cell1_D23_TX_L_90', 'cell1_D2_TX_L_90', 'cell1_D4_TX_L_90', 'cell1_D11_TX_L_90', 'cell1_D1P5_TX_L_90', 'cell_D1_TY_L_90', 'cell_D11_TY_L_90', 'cell_D14_TY_L_90', 'cell_D4_TY_L_90', 'cell_D3_TY_L_90' ], 'D1': [5, 2, 2, 6, 6, 5, 2, 2, 6, 6, 5, 2, 2, 6, 6] } df = pd.DataFrame(d)
高效解决方案
利用Pandas向量化字符串操作替代循环,通过构造多维度排序键实现自然排序,全程基于底层优化的C操作,适合大数量级数据:
# 1. 提取分组键和排序目标列 df['group1'] = df['cell'].str.split('_').str[0] df['group2'] = df['cell'].str.split('_').str[2] df['sort_target'] = df['cell'].str.split('_').str[1] # 2. 构造自然排序的多维度键:前缀字母 + 数字部分 + 剩余字符 df['sort_prefix'] = df['sort_target'].str.extract(r'([A-Za-z]+)')[0] df['sort_num'] = df['sort_target'].str.extract(r'(\d+)')[0].fillna(0).astype(int) df['sort_rest'] = df['sort_target'].str.replace(r'^[A-Za-z]+\d+', '', regex=True) # 3. 按分组键+排序键排序,清理临时列 df_sorted = df.sort_values( by=['group1', 'group2', 'sort_prefix', 'sort_num', 'sort_rest'] ).drop(columns=['group1', 'group2', 'sort_target', 'sort_prefix', 'sort_num', 'sort_rest']) print(df_sorted)
输出结果
排序后每组内的cell列会按第2段的字母数字顺序排列,比如:
cell_TX组顺序:cell_D1_TX_L_90→cell_D3_TX_L_90→cell_D4_TX_L_90→cell_D11_TX_L_90→cell_D14_TX_L_90cell1_TX组顺序:cell1_D2_TX_L_90→cell1_D4_TX_L_90→cell1_D11_TX_L_90→cell1_D1P5_TX_L_90→cell1_D23_TX_L_90
方案优势
- 全程使用Pandas向量化操作,避免Python循环的性能损耗,50万行数据处理时间可控制在秒级
- 无需额外依赖库,纯Pandas实现自然排序逻辑
- 排序键的多维度设计兼容带混合字符的场景(如
D1P5)
内容的提问来源于stack exchange,提问作者sandeep
相关产品推荐
相关产品推荐

