我有一个这样的数据框,想要在:
上应用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
度。我希望我解释得很好。
答案 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 < 180
,b < 180
- &gt;结果只是|a - b|
。由于|a - b| - 180
不能大于180,如果a - b
,则公式将简化为a > b
,如果b - a
,则公式将简化为b > a
。a < 0
,b < 0
- &gt;这里适用相同的逻辑。负面和它们的绝对差值都不能大于180.结果将是|a - b|
。a < 180
,b < 0
- &gt; a - b肯定会大于0。对于|a - b| > 180
的情况,我们应该查看另一个角度,这会转换为360 - |a - b|
。a < 0
,b < 180
- &gt;再次,类似于上面。如果绝对差值大于180,则计算360 - 绝对差值。 对于pandas部分:rolling(n)
创建大小为n的数组。对于2 :(第0行,第1行),(第1行,第2行),...使用apply
,将该公式应用于x[0]
是第一个元素(a)和{{x[1]
的每个滚动对1}}是第二个元素。