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

如何在Pandas DataFrame中按列值分组,拆分非连续重复值组

问题:Pandas 按连续列值分组并拆分非连续重复组

需要对Pandas DataFrame按State和Sales_Amt分组,但仅合并连续出现的相同值组;如果后续出现与之前分组值相同但非连续的情况,需拆分为新组。

原始数据

State   Dates      Sales_Amt
A       1/1/2023     123
A       2/1/2023     123
A       3/1/2023     321
A       4/1/2023     321
A       5/1/2023     123
A       6/1/2023     123
A       7/1/2023     123
B       1/1/2023     456
B       2/1/2023     456
B       3/1/2023     456
B       4/1/2023     789
B       5/1/2023     789
B       6/1/2023     789
B       7/1/2023     123
B       8/1/2023     123

期望结果

State   Start_Dates  End_Dates   Sales_Amt
A       1/1/2023     2/1/2023       123
A       3/1/2023     4/1/2023       321
A       5/1/2023     7/1/2023       123 
B       1/1/2023     3/1/2023       456
B       4/1/2023     6/1/2023       789
B       7/1/2023     8/1/2023       123

尝试的代码(无效)

df = (df.groupby(['State','Sales_Amt'],group_keys=True)
        .agg(Start_Dates=('Dates', np.min), 
             End_Dates=('Dates', np.max))
        .sort_values(['State','Start_Dates','End_Dates'],ascending=True)
        .reset_index()
     )

解决方案

问题原因

直接按State和Sales_Amt分组会将同一State下所有相同Sales_Amt的行合并,忽略了“连续”的要求,导致A组中两次出现的123被合并成一个区间,不符合需求。

实现步骤

  1. 转换日期格式:将Dates列转为datetime类型,确保日期计算准确(可选,但推荐)。
  2. 生成连续分组标识:通过对比当前行与上一行的State和Sales_Amt,标记新的分组,用累加值生成唯一组ID。
  3. 分组聚合:基于State、Sales_Amt和组ID分组,提取每个组的起始和结束日期。

完整代码

import pandas as pd
import numpy as np

# 加载原始数据(示例)
data = {
    'State': ['A', 'A', 'A', 'A', 'A', 'A', 'A', 'B', 'B', 'B', 'B', 'B', 'B', 'B', 'B'],
    'Dates': ['1/1/2023', '2/1/2023', '3/1/2023', '4/1/2023', '5/1/2023', '6/1/2023', '7/1/2023',
              '1/1/2023', '2/1/2023', '3/1/2023', '4/1/2023', '5/1/2023', '6/1/2023', '7/1/2023', '8/1/2023'],
    'Sales_Amt': [123, 123, 321, 321, 123, 123, 123, 456, 456, 456, 789, 789, 789, 123, 123]
}
df = pd.DataFrame(data)

# 转换Dates为datetime类型
df['Dates'] = pd.to_datetime(df['Dates'], format='%m/%d/%Y')

# 创建连续分组标识:当State或Sales_Amt与上一行不同时,生成新组
df['group_id'] = (df[['State', 'Sales_Amt']] != df[['State', 'Sales_Amt']].shift()).any(axis=1).cumsum()

# 分组聚合并整理结果
result = (df.groupby(['State', 'Sales_Amt', 'group_id'])
          .agg(Start_Dates=('Dates', 'min'),
               End_Dates=('Dates', 'max'))
          .reset_index()
          .drop('group_id', axis=1)
          .sort_values(['State', 'Start_Dates'])
          .reset_index(drop=True))

# 转换回原日期字符串格式(可选)
result['Start_Dates'] = result['Start_Dates'].dt.strftime('%m/%d/%Y')
result['End_Dates'] = result['End_Dates'].dt.strftime('%m/%d/%Y')

print(result)

输出结果

State Start_Dates End_Dates  Sales_Amt
0     A    1/1/2023  2/1/2023        123
1     A    3/1/2023  4/1/2023        321
2     A    5/1/2023  7/1/2023        123
3     B    1/1/2023  3/1/2023        456
4     B    4/1/2023  6/1/2023        789
5     B    7/1/2023  8/1/2023        123

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.27 23:22:08