You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何基于列中子串对DataFrame排序?解决子串干扰问题

问题描述

我有一个含字符串行的DataFrame,希望基于col1列对整个DataFrame排序,但部分行包含其他行的子串,导致排序混乱。

原始DataFrame

col1           col2        col3       col4
Animal           Tiger       Cat         Dog
Name             Adam       Grace       Julia
Street Name1    Pine St    Crown St    Palm Ave
Street Name2    Grey St    Tree St     New St
Color           Green        Blue       Yellow
Interest         Yes         No           Yes
Low Interest     No          No           Yes
High Interest    Yes         No           Yes
City2             x          z             y
City1             m          r             t

期望排序结果

col1           col2        col3       col4
Name             Adam       Grace       Julia
Street Name1    Pine St    Crown St    Palm Ave
Street Name2    Grey St    Tree St     New St   
City1             m          r             t
City2             x          z             y
Interest         Yes         No           Yes
High Interest    Yes         No           Yes    
Low Interest     No          No           Yes
Animal           Tiger       Cat         Dog
Color           Green        Blue       Yellow

尝试的代码及问题

我尝试了以下代码:

order = ['Name', 'Street Name', 'City', 'Interest','High Interest','Low Interest', 'Animal', 'Color']
df['order'] = df['col1'].apply(order)
df = df.sort_values(by = 'order').drop(columns = 'order')

但出现问题:由于"Name"是"Street Name"的子串,"Street Name"行排在了"Name"行之前,结果如下:

col1           col2        col3       col4
    Street Name1    Pine St    Crown St    Palm Ave
    Street Name2    Grey St    Tree St     New St   
    Name             Adam       Grace       Julia

更新说明:无法显式列出"Street Name1"、"Street Name2"等,因为末尾数字可能变化,最多可能到"Street Name7",无法预先定义数字。


解决方案

核心是给col1的字符串匹配精确的优先级分组,避免子串干扰,同时对带数字的项按数字排序。具体实现如下:

代码实现

import pandas as pd

# 原始数据构建DataFrame
data = {
    'col1': ['Animal', 'Name', 'Street Name1', 'Street Name2', 'Color', 'Interest', 'Low Interest', 'High Interest', 'City2', 'City1'],
    'col2': ['Tiger', 'Adam', 'Pine St', 'Grey St', 'Green', 'Yes', 'No', 'Yes', 'x', 'm'],
    'col3': ['Cat', 'Grace', 'Crown St', 'Tree St', 'Blue', 'No', 'No', 'No', 'z', 'r'],
    'col4': ['Dog', 'Julia', 'Palm Ave', 'New St', 'Yellow', 'Yes', 'Yes', 'Yes', 'y', 't']
}
df = pd.DataFrame(data)

# 定义优先级顺序,按期望的排序优先级排列
priority_order = ['Name', 'Street Name', 'City', 'Interest', 'High Interest', 'Low Interest', 'Animal', 'Color']

def get_sort_key(s):
    for idx, prefix in enumerate(priority_order):
        # 用startswith做前缀匹配,避免子串误匹配
        if s.startswith(prefix):
            # 对带数字的分组(如Street Name、City),提取数字做二级排序键
            if prefix in ('Street Name', 'City'):
                # 提取前缀后的数字部分,转为整数保证按数字大小排序
                num_part = s.replace(prefix, '').strip()
                return (idx, int(num_part) if num_part.isdigit() else 0)
            # 不带数字的分组直接返回优先级索引
            return (idx,)
    # 未匹配到的项放在最后
    return (len(priority_order),)

# 生成排序键并排序
df['sort_key'] = df['col1'].apply(get_sort_key)
df_sorted = df.sort_values(by='sort_key').drop(columns='sort_key')

print(df_sorted)

关键说明

  1. 前缀匹配替代子串包含:用startswith判断字符串是否以优先级项开头,这样"Street Name1"只会匹配"Street Name",不会误匹配"Name";
  2. 二级排序处理带数字项:对"Street NameN"、"CityN"这类带数字的项,提取数字转为整数,保证按数字顺序排序(如City1在City2前);
  3. 严格优先级分配:遍历优先级列表时,按期望的排序顺序匹配,确保每组项落在正确的排序位置。

内容的提问来源于stack exchange,提问作者mjoy

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.16 23:30:56