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

如何用Pandas识别非平衡面板数据中个体的状态变化?

解决非平衡面板数据中识别个体变量变化的问题

问题背景

处理非平衡面板数据时,需要按个体(id)识别随时间变化的job字段,生成change列:当当期job与上一期不同时标记为1,否则为0(每个个体的首条记录标记为0)。

示例数据:

import pandas as pd

df = pd.DataFrame(
    {
        "region": ["C1", "C1", "C2", "C2", "C2"],
        "id": [1, 1, 2, 2, 2],
        "date": ["01/01/2021", "01/02/2021", "01/01/2021", "01/02/2021", "01/03/2021"],
        "job": ["A", "A", "A", "B", "B"],
        "wage": [10, 10, 15, 25, 25],
        "change": [0, 0, 0, 1, 0]
    }
)

错误原因

尝试使用df.groupby(['id'])['job'].diff().fillna(0)时出现TypeError: unsupported operand type(s) for -: 'str' and 'str',因为diff()方法仅支持数值型数据的差分运算,无法对字符串类型执行减法操作。

解决方案

步骤1:确保数据按个体和时间排序

非平衡面板数据必须先按id和date排序,保证时间顺序正确:

df['date'] = pd.to_datetime(df['date'], format='%d/%m/%Y')
df = df.sort_values(['id', 'date']).reset_index(drop=True)

步骤2:生成change列

利用shift()方法将每个个体的上一期job值下移,与当期值比较,将布尔结果转为整数(1/0),并填充首行的缺失值为0:

# 简洁写法
df['change'] = (df.groupby('id')['job'].shift() != df['job']).astype(int).fillna(0)

或使用apply的写法:

df['change'] = df.groupby('id')['job'].apply(lambda x: x != x.shift()).astype(int).fillna(0)

验证结果

执行后生成的change列与预期一致:

regioniddatejobwagechange
C112021-01-01A100
C112021-02-01A100
C222021-01-01A150
C222021-02-01B251
C222021-03-01B250

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.13 19:30:55