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

Pandas按col1分组、col3排序后检测col2行间变化出错排查

解决DataFrame分组排序后检测相邻行数值变化的错误问题

问题重现

你需要按col1分组、按col3排序,同时检测col2中相邻行的数值变化,但当前代码运行结果不符合预期。

原始代码

import pandas as pd
import datetime

my_df = pd.DataFrame({'col1': ['a', 'a', 'a', 'b', 'b', 'b'],
                      'col2': [2, 2, 3, 5, 5, 5],
                      'col3': [datetime.date(2023, 2, 1),
                               datetime.date(2023, 3, 1),
                               datetime.date(2023, 4, 1),
                               datetime.date(2023, 2, 1),
                               datetime.date(2023, 3, 1),
                               datetime.date(2023, 4, 1)]})

my_df.sort_values(by=['col3'], inplace=True)
my_df_temp = my_df.groupby('col1')['col2'].apply(
    lambda x: x != x.shift(1)
).reset_index(name='col2_change')

原始DataFrame

col1  col2        col3
0    a     2  2023-02-01
1    a     2  2023-03-01
2    a     3  2023-04-01
3    b     5  2023-02-01
4    b     5  2023-03-01
5    b     5  2023-04-01

错误结果

col1  level_1  col2_change
0    a        0         True
1    a        1        False
2    a        2         True
3    b        3         True
4    b        4        False
5    b        5        False

错误原因分析

  1. 排序逻辑不严谨:仅按col3全局排序会导致不同col1的行交替出现,虽然组内col3顺序正确,但数据结构不够清晰,也不符合分组后排序的常规逻辑。
  2. 相邻比较逻辑偏差:每组第一行没有前置行,x.shift(1)返回NaN,而x != x.shift(1)会将NaN与值的比较结果判定为True,这不符合“无前置行则无变化”的预期。
  3. 结果格式冗余:reset_index后生成的level_1列是原DataFrame的索引,属于多余信息,且未将结果与原数据关联,实用性差。

修正方案

优化后的代码

import pandas as pd
import datetime

my_df = pd.DataFrame({'col1': ['a', 'a', 'a', 'b', 'b', 'b'],
                      'col2': [2, 2, 3, 5, 5, 5],
                      'col3': [datetime.date(2023, 2, 1),
                               datetime.date(2023, 3, 1),
                               datetime.date(2023, 4, 1),
                               datetime.date(2023, 2, 1),
                               datetime.date(2023, 3, 1),
                               datetime.date(2023, 4, 1)]})

# 按col1分组、col3排序,确保同组行连续且按时间有序
my_df = my_df.sort_values(by=['col1', 'col3'])

# 分组检测col2相邻变化,第一行标记为False(无前置行无变化)
my_df['col2_change'] = my_df.groupby('col1')['col2'].apply(
    lambda x: x.ne(x.shift()).fillna(False)
)

print(my_df)

正确结果

col1  col2        col3  col2_change
0    a     2  2023-02-01        False
1    a     2  2023-03-01        False
2    a     3  2023-04-01         True
3    b     5  2023-02-01        False
4    b     5  2023-03-01        False
5    b     5  2023-04-01        False

关键修正点

  • 排序优化:按['col1', 'col3']排序,确保同一分组的行连续排列,符合分组后排序的逻辑。
  • 比较逻辑修正:使用x.ne(x.shift())(等价于x != x.shift())生成变化标记,再用fillna(False)将每组第一行的NaN替换为False,贴合实际需求。
  • 结果整合:直接将结果赋值为原DataFrame的新列,避免冗余列,同时保留完整数据上下文。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.16 10:34:51