首页 > 解决方案 > 制作自定义移位函数以滞后于缺少观察的数据框

问题描述

所以我的数据框中缺少一些句点,但我仍然希望能够适当地移动数据。这是我写的

def custom_lag(df, lag_distance, columns_to_lag, reference_column):
    shape = np.zeros((len(df),len(columns_to_lag)))
    new_cols_prefix = "lag"+str(lag_distance)+"_"
    new_cols = [new_cols_prefix + col for col in columns_to_lag]
    lagged_df = pd.DataFrame(shape, index=df.index, columns=new_cols)

    ref = df[reference_column]
    for index, time in zip(ref.index, ref.values):
        desired_row = df[ref == time+lag_distance]
        lagged_df.loc[index, new_cols] = desired_row[columns_to_lag].to_numpy() if len(desired_row) != 0 else [np.nan]*len(new_cols)
    return lagged_df[new_cols]

df.groupby('id').apply(custom_lag, 1, ['prc'], 'period')

但不幸的是,这会返回一个带有重复项的 multidex。我想像官方的 shift 函数一样,我可以将新列分配回我的原始数据框中。

如何解决这个问题的想法?

如果有更好的解决方案,我会全力以赴。这比我希望的要慢得多。

这是 df 可能看起来的示例

df = pd.DataFrame({
              'id':[1,1,1,1,1,1,
                   2,2,2,2,
                   3,3,3],
              'period':[1,2,3,5,6,7,
                       2,4,6,7,
                       1,2,3],
              'prc':[5,4,6,5,4,2,
                     8,7,6,5,
                    6,3,4]})

看起来像

    id  period  prc
0    1       1    5
1    1       2    4
2    1       3    6
3    1       5    5
4    1       6    4
5    1       7    2
6    2       2    8
7    2       4    7
8    2       6    6
9    2       7    5
10   3       1    6
11   3       2    3
12   3       3    4

看看如何缺少期间数据?这就是使定期轮班不受欢迎的原因。

标签: pandas

解决方案


您可以执行以下操作:

# create lagged col
df['lag_prc'] = df.groupby('id')['prc'].shift(-1)

# set values as NA if period differs by 1
df['lag_prc'] = (df['period']
                 .shift(-1)
                 .sub(df['period'])
                 .eq(1)
                 .mul(1)
                 .replace(0, np.nan) * df['lag_prc'])

print(df)

    period  id  prc  lag_prc
0        1   1    5      4.0
1        2   1    4      6.0
2        3   1    6      NaN
3        5   1    5      4.0
4        6   1    4      2.0
5        7   1    2      NaN
6        2   2    8      NaN
7        4   2    7      NaN
8        6   2    6      5.0
9        7   2    5      NaN
10       1   3    6      3.0
11       2   3    3      4.0
12       3   3    4      NaN

推荐阅读