在 python 中使用滞后函数来移动数据并创建新变量

Lag Function usage in python to shift the data and create new variables

我有如下数据集:

'FIRST'和'SECOND'变量各有八个组合(可以改变)'SCORE' 每个组合都有一个值

     FIRST  SECOND  SCORE
0       1       1  38147
1       2       1    567
2       3       1      0
3       4       1      0
4       5       1      0
5       6       1      0
6       7       1      0
7       8       1      0
8       1       2   3099
9       2       2  30460
10      3       2   2372
11      4       2      0
12      5       2      0
13      6       2      0
14      7       2      0
15      8       2    267

我想创建 8 个后缀为 'S' 的新变量(新变量的数量与 'FIRST' 或 'SECOND' 和 在每个新变量中将 'SCORE' 的值偏移一格。

期望输出

      FIRST  SECOND  SCORE     S1       S2       S3       S4       S5      S6      S7   S8
0       1       1  38147      NaN      NaN      NaN      NaN      NaN      NaN      NaN NaN
1       2       1    567  38147.0      NaN      NaN      NaN      NaN      NaN      NaN NaN
2       3       1      0    567.0  38147.0      NaN      NaN      NaN      NaN      NaN NaN
3       4       1      0      0.0    567.0  38147.0      NaN      NaN      NaN      NaN NaN
4       5       1      0      0.0      0.0    567.0  38147.0      NaN      NaN      NaN NaN
5       6       1      0      0.0      0.0      0.0    567.0  38147.0      NaN      NaN NaN
6       7       1      0      0.0      0.0      0.0      0.0    567.0  38147.0      NaN NaN
7       8       1      0      0.0      0.0      0.0      0.0      0.0    567.0  38147.0 NaN
8       1       2   3099      NaN      NaN      NaN      NaN      NaN      NaN      NaN NaN
9       2       2  30460   3099.0      NaN      NaN      NaN      NaN      NaN      NaN NaN
10      3       2   2372  30460.0   3099.0      NaN      NaN      NaN      NaN      NaN NaN
11      4       2      0   2372.0  30460.0   3099.0      NaN      NaN      NaN      NaN NaN
12      5       2      0      0.0   2372.0  30460.0   3099.0      NaN      NaN      NaN NaN
13      6       2      0      0.0      0.0   2372.0  30460.0   3099.0      NaN      NaN NaN
14      7       2      0      0.0      0.0      0.0   2372.0  30460.0   3099.0      NaN NaN
15      8       2    267      0.0      0.0      0.0      0.0   2372.0  30460.0   3099.0 NaN

python有没有办法做到这一点?

下面是 R 语言中的等效代码,它使用 data.table 包

完成此操作

R码

number_of_bids <- 8

test[, paste0('S',seq(1:number_of_bids)):= shift(SCORE,1:number_of_bids, NA_real_,"lag"), by = SECOND]

下面是输入python数据供参考:


#Ceate dataframe
data = [
    [1,1,38147],
    [2,1,567],
    [3,1,0],
    [4,1,0],
    [5,1,0],
    [6,1,0],
    [7,1,0],
    [8,1,0],
    [1,2,3099],
    [2,2,30460],
    [3,2,2372],
    [4,2,0],
    [5,2,0],
    [6,2,0],
    [7,2,0],
    [8,2,267],
       
]

#dataframe
test1 = pd.DataFrame(data, columns = ['FIRST', 'SECOND', 'SCORE'])

两种方法:

  1. .shiftpd.concat:

    In [324]: pd.concat([dat,dat.groupby(['SECOND'])['SCORE'].shift(), dat.groupby(['SECOND'])['SCORE'].shift(2)], axis=1)
    Out[324]: 
        FIRST  SECOND  SCORE    SCORE    SCORE
    0       1       1  38147      NaN      NaN
    1       2       1    567  38147.0      NaN
    2       3       1      0    567.0  38147.0
    3       4       1      0      0.0    567.0
    4       5       1      0      0.0      0.0
    5       6       1      0      0.0      0.0
    6       7       1      0      0.0      0.0
    7       8       1      0      0.0      0.0
    8       1       2   3099      NaN      NaN
    9       2       2  30460   3099.0      NaN
    10      3       2   2372  30460.0   3099.0
    11      4       2      0   2372.0  30460.0
    12      5       2      0      0.0   2372.0
    13      6       2      0      0.0      0.0
    14      7       2      0      0.0      0.0
    15      8       2    267      0.0      0.0
    

    (并重命名后续列)。

  2. for 循环和 .shift:

    In [337]: for lag in range(1, 5):
         ...:   dat['S' + str(lag)] = dat.groupby(['SECOND'])['SCORE'].shift(lag)
         ...: 
    
    In [338]: dat
    Out[338]: 
        FIRST  SECOND  SCORE       S1       S2       S3       S4
    0       1       1  38147      NaN      NaN      NaN      NaN
    1       2       1    567  38147.0      NaN      NaN      NaN
    2       3       1      0    567.0  38147.0      NaN      NaN
    3       4       1      0      0.0    567.0  38147.0      NaN
    4       5       1      0      0.0      0.0    567.0  38147.0
    5       6       1      0      0.0      0.0      0.0    567.0
    6       7       1      0      0.0      0.0      0.0      0.0
    7       8       1      0      0.0      0.0      0.0      0.0
    8       1       2   3099      NaN      NaN      NaN      NaN
    9       2       2  30460   3099.0      NaN      NaN      NaN
    10      3       2   2372  30460.0   3099.0      NaN      NaN
    11      4       2      0   2372.0  30460.0   3099.0      NaN
    12      5       2      0      0.0   2372.0  30460.0   3099.0
    13      6       2      0      0.0      0.0   2372.0  30460.0
    14      7       2      0      0.0      0.0      0.0   2372.0
    15      8       2    267      0.0      0.0      0.0      0.0
    

数据

import pandas as pd
dat = pd.DataFrame({
  'FIRST': pd.Series([1, 2, 3, 4, 5, 6, 7, 8, 1, 2, 3, 4, 5, 6, 7, 8],dtype='int64',index=pd.Int64Index([0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15], dtype='int64')),
  'SECOND': pd.Series([1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2],dtype='int64',index=pd.Int64Index([0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15], dtype='int64')), 
  'SCORE': pd.Series([38147, 567, 0, 0, 0, 0, 0, 0, 3099, 30460, 2372, 0, 0, 0, 0, 267],dtype='int64',index=pd.Int64Index([0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15], dtype='int64'))
}, index=pd.Int64Index([0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15], dtype='int64'))