【问题标题】:How to get the lagged values of a variable based on groups with pandas?如何根据熊猫组获取变量的滞后值?
【发布时间】:2021-02-26 11:54:04
【问题描述】:

我想找到按连续值对数据进行分组的最有效方法,并创建一个新变量,在每个组中给出前一组的值(第一组除外,其中值应该相同)。

我现在可能不是很清楚,所以这里是一个玩具示例:

import pandas as pd

var = [1,1,1,2,2,3,1,1,2,4,4,4]
toy_df = pd.DataFrame(var, columns = ['var'])

我想要的输出如下:

desired_output = pd.DataFrame(
                {'var': var,
                 'lagged_var':[1,1,1,1,1,2,3,3,1,2,2,2]}
                )

    var  lagged_var
0     1           1
1     1           1
2     1           1
3     2           1
4     2           1
5     3           2
6     1           3
7     1           3
8     2           1
9     4           2
10    4           2
11    4           2

到目前为止,我已经想出了以下功能:

def make_lag(var):
    groups = ( var.shift() != var ).cumsum()
    var_shifted = pd.Series([0]*len(var))
    for n_gp in groups.unique():
        if n_gp == 1: 
            var_shifted[groups == n_gp] = var[groups == n_gp]
        else:
            var_shifted[groups == n_gp] = var[groups == n_gp - 1].iloc[0]
    
    return ( var_shifted )

toy_df['lagged_values'] = toy_df.apply(lambda x: make_lag(x))

提供所需的输出。但是,我怀疑它的效率非常低,因为它涉及遍历所有行。有人知道产生相同输出的矢量化方法吗?(我必须在数百个很长的时间序列中重复这个任务,这真的很省时间!)

非常感谢!

【问题讨论】:

    标签: python pandas grouping lag


    【解决方案1】:

    使用Series.shift作为下一个值,如果匹配原始值则替换,然后通过向前和向后填充缺失值来重复值:

    s = toy_df['var'].shift()
    toy_df['new'] = s.mask(toy_df['var'].eq(s)).ffill().bfill()
    print (toy_df)
        var  new
    0     1  1.0
    1     1  1.0
    2     1  1.0
    3     2  1.0
    4     2  1.0
    5     3  2.0
    6     1  3.0
    7     1  3.0
    8     2  1.0
    9     4  2.0
    10    4  2.0
    11    4  2.0
    

    如果要将值转换为整数:

    s = toy_df['var'].shift()
    toy_df['new'] = s.mask(toy_df['var'].eq(s)).ffill().bfill().astype(int)
    print (toy_df)
     var  new
    0     1    1
    1     1    1
    2     1    1
    3     2    1
    4     2    1
    5     3    2
    6     1    3
    7     1    3
    8     2    1
    9     4    2
    10    4    2
    11    4    2
    

    【讨论】:

      猜你喜欢
      • 2021-08-16
      • 2019-09-08
      • 1970-01-01
      • 2021-04-25
      • 2020-07-26
      • 1970-01-01
      • 1970-01-01
      • 2018-11-27
      • 2020-06-21
      相关资源
      最近更新 更多