我有一个像这样的数据框,想要应用 diff 函数:
test = pd.DataFrame({ 'Observation' : ['0','1','2',
'3','4','5',
'6','7','8'],
'Value' : [30,60,170,-170,-130,-60,-30,10,20]
})
Observation Value
0 30
1 60
2 170
3 -170
4 -130
5 -60
6 -30
7 10
8 20
“值”列以度为单位。那么, -170
之间的区别和170
应该是20
,不是-340
。换句话说,当 d2*d1 < 0
,而不是 d2-d1
,我想要360-(abs(d1)+abs(d2))
这就是我尝试的原因。但后来我不知道如何在不使用 for 循环的情况下继续它:
test['Value_diff_1st_attempt'] = test['Value'].diff(1)
test['sign_temp'] = test['Value'].shift()
test['Sign'] = np.sign(test['Value']*test['sign_temp'])
结果应如下所示:
Observation Value Delta_Value
0 30 NAN
1 60 30
2 170 110
3 -170 20
4 -130 40
5 -60 70
6 -30 30
7 10 40
8 20 10
最终我想得到所有正值的差异大小。谢谢。
更新:所以,值结果来自 math.atan2
功能。这些值来自 0<theta<180
或-180<theta<0
。当我们处理从170
开始的方向变化时,问题就出现了。 (左上角)至-170
(左下角)例如,更改实际上只是 20
度。然而,当我们从-30
开始时(右下角)至10
(右上角),变化真是40
度。我希望我解释得很好。
最佳答案
我相信这应该有效(从 @JasonD's answer 获取定义):
test["Value"].rolling(2).apply(lambda x: 180 - abs(abs(x[0] - x[1]) - 180))
Out[45]:
0 NaN
1 30.0
2 110.0
3 20.0
4 40.0
5 70.0
6 30.0
7 40.0
8 10.0
Name: Value, dtype: float64
<小时/>
它是如何工作的:
根据你的问题,两个角度a和b在0
之间和+/-180
。对于 0 < d < 180
我会写d < 180
和 -180 < d < 0
我会写d < 0
。有四种可能:
-
a < 180
,b < 180
-> 结果就是|a - b|
。自从|a - b| - 180
不能大于 180,公式将简化为a - b
如果a > b
和b - a
如果b > a
. -
a < 0
,b < 0
-> 同样的逻辑也适用于此。均为负数且其绝对差不能大于 180。结果将是|a - b|
. -
a < 180
,b < 0
-> a - b 肯定会大于 0。对于|a - b| > 180
的情况,我们应该看看另一个角度,这转化为360 - |a - b|
. -
a < 0
,b < 180
-> 再次,与上面类似。如果绝对差值大于 180,则计算 360 - 绝对差值。
对于 pandas 部分:rolling(n)
创建大小为 n 的数组。对于 2:(第 0 行,第 1 行),(第 1 行,第 2 行),... 与 apply
,您将该公式应用于每个滚动对,其中 x[0]
是第一个元素 (a) 和 x[1]
是第二个元素。
关于python - 在选定的行上应用 diff 以比较 math.atan2 的角度,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37122199/