【问题标题】:How to identify changes in a variable per person per time (in panel data)?如何识别每人每次变量的变化(在面板数据中)?
【发布时间】:2019-10-31 17:27:16
【问题描述】:

我有面板数据(每个 ID 在不同时间点的重复观察)。数据不平衡(存在差距)。我需要检查并可能调整多年来每个人的变量变化。

我尝试了两个版本。首先,for 循环设置,首先访问每个人和每个人的每一年。第二,与groupby 的单行组合。 Groupby 对我来说看起来更优雅。这里的主要问题是确定“下一个元素”。我假设在一个循环中我可以用一个计数器来解决这个问题。

这是我的 MWE 面板数据:

import pandas as pd
df = pd.DataFrame({'year': ['2003', '2004', '2005', '2006', '2007', '2008', '2009','2003', '2004', '2005', '2006', '2007', '2008', '2009'],
                   'id': ['1', '1', '1', '1', '1', '1', '1', '2', '2', '2', '2', '2', '2', '2'],
                   'money': ['15', '15', '15', '16', '16', '16', '16', '17', '17', '17', '18', '17', '17', '17']}).astype(int)
df

这是每个人的时间序列的样子:

import matplotlib.pyplot as plt
import pandas as pd
import numpy as np

fig, ax = plt.subplots()

for i in df.id.unique():
    df[df['id']==i].plot.line(x='year', y='var', ax=ax, label='id = %s'%i)
    df[df['id']==i].plot.scatter(x='year', y='var', ax=ax)
    plt.xticks(np.unique(df.year),rotation=45)    

这是我想要实现的目标:对于每个人,比较值的时间序列并丢弃与其前身值不同的每个继任者(标识红色圆圈)。然后我会尝试不同的策略来处理它:

  • 丢弃(非常不确定):如果继任者不同,则丢弃它
  • 平滑(绝对值):如果后继值相差(例如)1 个单位,则为其分配前导值
  • 平滑(相对值):如果后继值相差(例如)1%,则为其分配前导值

解决办法

df['money_difference'] = df['money']-df.groupby('id')['money'].shift(1)
df_new = df.drop(df[df['money_difference'].abs()>0].index)

平滑的想法

# keep track of change of variable by person and time
df['money_difference'] = df['money']-df.groupby('id')['money'].shift(1)
# first element has no precursor, it will be NaN, replace this by 0
df = df.fillna(0)
# now: whenever change_of_variable exceeds a threshold, replace the value by its precursor - not working so far
df['money'] = np.where(abs(df['money_difference'])>=1, df['money'].shift(1), df['money'])

【问题讨论】:

    标签: python pandas loops pandas-groupby panel-data


    【解决方案1】:

    要获取数据库中的下一个事件,您可以使用groupbyshift 的组合,然后对上一个事件进行减法:

    df['money_difference'] =df.groupby(['year', 'id'])['money'].shift(-1)-df['money']
    

    【讨论】:

    • 这是一个很好的功能。不知道shift。但是我更改了年份组件,因为当我比较所有人年组合时它只给了我 NAN(这些最大值中只有 1 个)df['money_difference'] = df.groupby('id')['money'].shift(-1)-df['money'] 仍然报告差异“为时过早”,我得到 NAN最后一个(因为它没有继任者,我猜这没关系)。
    • 你的最后一个或第一个条目都是空的,我认为 shift 给你更多的可能性,我也在这里学习了 shift
    • 当我平滑数据而不是丢弃它时,您能否也给我一个提示如何包含replace 函数?像这样df['money'].replace(df['money_difference'].abs()>1, df['money'].shift(1))
    • 你要平滑哪个部分?您的列是否需要 if 条件?这可以通过 np.where 来完成,这里的 ocmments 是一个很好的例子:stackoverflow.com/questions/52270185/…
    • 我会检查的。在 MWE 数据中,图片 ID=2 我需要在 year=2006 处平滑峰值的选项。它可能被认为是异常值、误报或类似情况。所以当偏差很小的时候,我想用它的前驱值来代替它。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-12-03
    • 2022-11-26
    • 1970-01-01
    • 2017-10-09
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多