在选定的行上应用差异以比较来自 math.atan2 的角度

Applying diff on selected rows for comparing angles from math.atan2

我有一个像这样的数据框,想要应用 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

'Value' 列以度为单位。所以,-170170 之间的差异应该是 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 if a > bb - a if 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] 是第二个元素。