仅使用 Numpy(无 pandas)的 Groupby 移位(滞后值)模拟

Groupby shift (lagged values) analogue with only Numpy (no pandas)

我有一个如下所示的数据框:

          id    date       v1
0          0  1983.0    1.574
1          0  1984.0    1.806
2          0  1985.0    4.724
3          1  1986.0    0.320
4          1  1987.0    3.414
     ...     ...      ...
107191  9874  1993.0   52.448
107192  9874  1994.0  108.652
107193  9875  1992.0    1.597
107194  9875  1993.0    3.134
107195  9875  1994.0    7.619

我想生成一个新列,其中 v1 的滞后值按 id 排序。在 pandas 我会使用

df.groupby('id')['v1'].shift(-1)

但是,我想仅使用 Numpy 以纯 matrix/array 形式翻译它。在 Numpy 中获得类似物的最直接方法是什么?我需要避免使用 pandas 工具,因为我想稍后使用 Numba @jit。

IIUC,您希望纯粹在 numpy 中实现 df.groupby('id')['v1'].shift(-1)。这是由一个grouper和一个shift方法组成。

对于具有第一个分组列和第二个值列的二维数组,numpy 中的 groupby() 等效项是 -

np.split(arr[:,1], np.unique(arr[:, 0], return_index=True)[1][1:])

一维数组在 numpy 中的 shift() 等效项是 -

np.append(np.roll(arr,-1)[:-1], np.nan)

把这2个放在一起就可以得到你想要的-

#2D array with only id and v1 as columns
arr = df[['id','v1']].values   

#Groupby based on id
grouper = np.split(arr[:,1], np.unique(arr[:, 0], return_index=True)[1][1:]) 

#apply shift to grouped elements
shift = [np.append(np.roll(i,-1)[:-1], np.nan) for i in grouper] 

#stack them as a single array
new_col = np.hstack(shift) 

#set as column
df['shifted'] = new_col 

测试虚拟数据 -

#Dummy data
idx = [0,0,0,0,0,1,1,1,1,1,1,2,2,2,2,3,3,3,3,3]
val = np.arange(len(idx))
arr = np.array([idx, val]).T
df = pd.DataFrame(arr, columns=['id','v1'])

#apply grouped shifting
arr = df[['id','v1']].values
grouper = np.split(arr[:,1], np.unique(arr[:, 0], return_index=True)[1][1:])
shift = [np.append(np.roll(i,-1)[:-1], np.nan) for i in grouper]
new_col = np.hstack(shift)
df['shifted'] = new_col

print(df)
    id  v1  shifted
0    0   0      1.0
1    0   1      2.0
2    0   2      3.0
3    0   3      4.0
4    0   4      NaN
5    1   5      6.0
6    1   6      7.0
7    1   7      8.0
8    1   8      9.0
9    1   9     10.0
10   1  10      NaN
11   2  11     12.0
12   2  12     13.0
13   2  13     14.0
14   2  14      NaN
15   3  15     16.0
16   3  16     17.0
17   3  17     18.0
18   3  18     19.0
19   3  19      NaN