如果标题令人困惑,我很抱歉,我会尽力解释这个问题。我在这里有一个示例数据集:示例1
Segment Reach OutSeg Elevation
1 1 3 50
1 2 3 74
1 3 3 87
1 4 3 53
1 5 3 97
2 1 3 16
2 2 3 14
2 3 3 31
2 4 3 35
2 5 3 27
3 1 4 193
3 2 4 176
3 3 4 158
3 4 4 154
4 1 6 21
4 2 6 45
4 3 6 42
4 4 6 22
4 5 6 22
5 1 6 10
5 2 6 21
5 3 6 14
5 4 6 16
我想按照Reach的顺序,计算Elevation沿着每个Segment编号的移动平均值(窗口为3(,但是,如果Segment具有OutSeg值,我希望每个Segment末尾的移动平均线使用从其引用Segment(OutSeg(开始的Elevation值。例如,在Segment 1 Reach 5(1,5(处,我希望移动平均值考虑(1,4(、(1,5和(3,1(处的值。
我相信可能需要某种for循环。。。我试过下面的代码,但它只计算每组内的移动平均值:
df["moving"]=df.groupby("Segment"(["Elevation"].transform(lambda x:x.rolling(3,1(df["moving"] = df.groupby("Segment")["Elevation"].transform(lambda x: x.rolling(3,1)
提前感谢!
我无法想象一种完全矢量化的方式,所以我只会在Segment
上使用groupby来应用特定的函数。该函数将添加OutSeg
子数据帧中的第一行(如果有的话(,计算滚动平均值,并且只返回原始行。
代码可能是:
df = df.sort_values(['Segment', 'Reach']) # ensure correct order
def tx(dg):
seg = dg['Segment'].iat[0]
outseg = dg['OutSeg'].iat[0]
x = pd.concat([dg, df[df['Segment'] == outseg].head(1)])
y = x['Elevation'].rolling(3, 1, center=True).mean()
return(y[x['Segment'] == seg])
df['Mean3'] = df.groupby('Segment', as_index=False, group_keys=False).apply(tx)
print(df)
它给出:
Segment Reach OutSeg Elevation Mean3
0 1 1 3 50 62.000000
1 1 2 3 74 70.333333
2 1 3 3 87 71.333333
3 1 4 3 53 79.000000
4 1 5 3 97 114.333333
5 2 1 3 16 15.000000
6 2 2 3 14 20.333333
7 2 3 3 31 26.666667
8 2 4 3 35 31.000000
9 2 5 3 27 85.000000
10 3 1 4 193 184.500000
11 3 2 4 176 175.666667
12 3 3 4 158 162.666667
13 3 4 4 154 111.000000
14 4 1 6 21 33.000000
15 4 2 6 45 36.000000
16 4 3 6 42 36.333333
17 4 4 6 22 28.666667
18 4 5 6 22 22.000000
19 5 1 6 10 15.500000
20 5 2 6 21 15.000000
21 5 3 6 14 17.000000
22 5 4 6 16 15.000000