组内变量移位

2024-04-26 11:57:43 发布

您现在位置:Python中文网/ 问答频道 /正文

我有一个数据帧:

c1   Lag  Val1  
A    3    10
A    1    5
A    2    20
A    2    15
A    1    10
B    1    25
B    2    10

我想创建一个新的字段val2,这样val2中的每个值都是val2中的值,并按滞后行数进行移位。这里比较棘手的部分是移位应该发生在字段c1中定义的组中,这样输出看起来像

c1   Lag  Val1  Val2
A    3    10    15
A    1    5     20
A    2    20    10
A    2    15    NaN
A    1    10    NaN
B    1    25    10
B    2    10    NaN

我一直在尝试

df['Val2'] = df.groupby(['c1'])['Val1'].apply(lambda x:x.shift(df.Lag))

没有用,得到一个“一系列的真值是模糊的。”错误。谢谢你的帮助。谢谢!你知道吗


Tags: 数据lambdadfshift定义nanlagapply
2条回答

您可以通过self-merge和对索引的一点操作来实现这一点:

# Copy and keep only the columns that are relevant
df2 = df.rename(columns={'Val1': 'Val2'}).drop(columns='Lag').copy()

# Shift the index
df.index = df.index+df.Lag

# Merge, requiring match on shifted index and within group.
df.reset_index().merge(df2.reset_index(), on=['index', 'c1'], how='left').drop(columns='index')

输出:

  c1  Lag  Val1  Val2
0  A    3    10  15.0
1  A    1     5  20.0
2  A    2    20  10.0
3  A    2    15   NaN
4  A    1    10   NaN
5  B    1    25  10.0
6  B    2    10   NaN

您很可能需要为apply编写自己的函数。这样做是可行的,但可能有一种比迭代行和重复计算行移位更有效的方法。。。你知道吗

def shift_rows(g):
    g['Val2'] = np.nan
    for i,r in g.iterrows():
        g.at[i, 'Val2'] = g['Val1'].shift(-r['Lag'])[i]
    return g

output = df.groupby('c1').apply(shift_rows)
print(output)

  c1  Lag  Val1  Val2
0  A    3    10  15.0
1  A    1     5  20.0
2  A    2    20  10.0
3  A    2    15   NaN
4  A    1    10   NaN
5  B    1    25  10.0
6  B    2    10   NaN

其思想是遍历groupby对象的每一行,使用Lag中的值来计算行移位,然后提取所需的新值。这将被存储到该行的Val2中,并返回整个组

相关问题 更多 >