在所选行上应用diff以比较math.atan2

时间:2016-05-09 17:46:36

标签: python pandas diff angle 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

专栏&#39;价值&#39;是度。因此,-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度。我希望我解释得很好。

1 个答案:

答案 0 :(得分:2)

我相信这应该有效(从@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 < 180b < 180 - &gt;结果只是|a - b|。由于|a - b| - 180不能大于180,如果a - b,则公式将简化为a > b,如果b - a,则公式将简化为b > a
  • a < 0b < 0 - &gt;这里适用相同的逻辑。负面和它们的绝对差值都不能大于180.结果将是|a - b|
  • a < 180b < 0 - &gt; a - b肯定会大于0。对于|a - b| > 180的情况,我们应该查看另一个角度,这会转换为360 - |a - b|
  • a < 0b < 180 - &gt;再次,类似于上面。如果绝对差值大于180,则计算360 - 绝对差值。

对于pandas部分:rolling(n)创建大小为n的数组。对于2 :(第0行,第1行),(第1行,第2行),...使用apply,将该公式应用于x[0]是第一个元素(a)和{{x[1]的每个滚动对1}}是第二个元素。