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

按Name分组查找DataFrame各列连续相同值的起止索引

问题背景

给定如下Pandas DataFrame:

df = pd.DataFrame({'Name': ['Tesla','Tesla','Tesla','Toyota','Ford','Ford','Ford','BMW','BMW','BMW','Mercedes','Mercedes','Mercedes'],
                   'Type': ['Model X','Model X','Model X','Corolla','Bronco','Bronco','Mustang','3 Series','-','-','Alpha','Alpha','S-Class'],
                   'Year': [2015, 2015, 2015, 2017, 2018, 2018, 2020, 2015, 2015, 2017, 2018, 2018, 2020],
                   'Price': [85000, 90000, 95000, 20000, 35000, 35000, 45000, 40000, 40000, 65000, 50000, 50000, 75000],
                   'Color': ['White','White','White','Red','Blue','Blue','Yellow','Silver','Silver','Black','White','White','Black']
                  })

数据展示如下:

Name    Type     Year   Price   Color
0   Tesla   Model X  2015   85000   White
1   Tesla   Model X  2015   90000   White
2   Tesla   Model X  2015   95000   White
3   Toyota  Corolla  2017   20000   Red
4   Ford    Bronco   2018   35000   Blue
5   Ford    Bronco   2018   35000   Blue
6   Ford    Mustang  2020   45000   Yellow
7   BMW     3 Series 2015   40000   Silver
8   BMW     -        2015   40000   Silver
9   BMW     -        2017   65000   Black
10  Mercedes Alpha   2018   50000   White
11  Mercedes Alpha   2018   50000   White
12  Mercedes S-Class 2020   75000   Black
需求说明

需按Name列分组,为其他每一列查找连续相同值对应的start index(起始索引)和end index(结束索引),将结果存储为{起始索引:结束索引}的字典。示例:

  • Tesla分组中,Type列的Model X连续出现,对应字典项为0:2;
  • Color列中Blue连续出现在索引4-5,对应字典项为4:5;
  • Year列中2015在Tesla分组连续出现,对应字典项为0:2。

预期输出如下:
Name:

{0: 2, 3: 3, 4: 6, 7: 9, 10: 12}

Type:

{0: 2, 3: 3, 4: 5, 6: 6, 7: 7, 8: 9, 10: 11, 12: 12}

Year:

{0: 2, 3: 3, 4: 5, 6: 6, 7: 8, 9: 9, 10: 11, 12: 12}

Price:

{0: 0, 1: 1, 2: 2, 3: 3, 4: 5, 6: 6, 7: 8, 9: 9, 10: 11, 12: 12} 

Color:

{0: 2, 3: 3, 4: 5, 6: 6, 7: 8, 9: 9, 10: 11, 12:12}
尝试的代码
def find_indices(df, column):
    df1 = df.index.to_series().groupby(df[column]).agg(['first', 'last']).reset_index()
    df1 = df1.sort_values("first").reset_index()
    first_last_rows = df1.set_index('first')['last'].to_dict()
    print(column + ":")
    print(first_last_rows)
遇到的问题

运行上述代码后,Year和Color列的输出结果不符合预期,结束索引跨了不同的Name分组,没有正确识别同一Name分组内的连续相同值:

Year:
{0: 8, 3: 9, 4: 11, 6: 12}
Color:
{0: 11, 3: 3, 4: 5, 6: 6, 7: 8, 9: 12}

需要修正代码,实现按Name分组查找各列连续相同值的起止索引。

解决方案

核心思路是先按Name分组,再在每个分组内识别连续相同值的块,具体实现如下:

import pandas as pd

def find_indices(df, column):
    # 生成连续相同值的分组标识:同一Name内,值变化或Name变化时递增
    df['group_id'] = (df[column] != df[column].shift()) | (df['Name'] != df['Name'].shift())
    df['group_id'] = df['group_id'].cumsum()
    
    # 按group_id分组,获取每个组的首尾索引
    result_df = df.groupby('group_id')['index'].agg(['first', 'last'])
    
    # 转换为有序字典
    result_dict = dict(sorted(result_df.set_index('first')['last'].to_dict().items()))
    
    print(f"{column}:")
    print(result_dict)

# 保留原始索引到单独列
df['index'] = df.index

# 遍历所有列生成结果
for col in df.columns.drop('index'):
    find_indices(df, col)

代码说明

  • group_id生成:通过判断当前行的目标列值或Name是否与前一行不同,生成布尔值后累加,确保同一Name内的连续相同值属于同一个分组;
  • 按group_id分组后直接取首尾索引,避免跨Name分组的问题;
  • 最后对字典按起始索引排序,保证输出顺序符合预期。

运行上述代码后,输出结果将完全匹配预期。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.03 01:55:35