Seb*_*itz 5 algorithm math geometry median
我有一个角度列表,想摆脱异常值。我的第一个想法是计算中位数。不幸的是存在“环绕”问题。我不知道定义一组角度(或时钟位置)的中值的“正确”方法。
我的想法是先计算平均值,然后用它打破另一侧的圆。
Example:
{6, 50, 52, 54, 60, 250} (in degree, 0-360)
average ~ 39
new range [-219, 219) -> new order 250, 6, 50, 52, 54, 60, 250
52 or 54 as median
Run Code Online (Sandbox Code Playgroud)
这是一个好方法,还是我不知道有更好的方法?
有点相关:这个问题展示了计算角度均值的方法。
您可以使用您链接的问题中显示的方法:将平均值计算为角度的累积单位向量的角度。在我看来,这种方法不太适合大型向量集。
\n\n还有另一种适用于加权插值的方法。它不需要任何三角函数,这意味着您可以使用度数数据,而无需将其转换为弧度。
\n\n在这种方法中,所有角度必须在 0\xc2\xb0 和 360\xc2\xb0 之间。如果它们位于外部,则必须将它们带入此范围,例如-5\xc2\xb0 变为355\xc2\xb0。然后进行成对加权平均,当角度之差超过半圆时调整角度,以便始终对角度之间较短的弧进行平均。平均后,所得角度范围为 0\xc2\xb0 到 360\xc2\xb0。
\n\ndef angle_interpol(a1, w1, a2, w2):\n """Weighted avarage of two angles a1, a2 with weights w1, w2\n\n diff = a2 - a1 \n if diff > 180: a1 += 360\n elif diff < -180: a1 -= 360\n\n aa = (w1 * a1 + w2 * a2) / (w1 + w2)\n\n if aa > 360: aa -= 360\n elif aa < 0: aa += 360\n\n return aa\n\ndef angle_mean(angle): \n """Unweighted average of a list of angles"""\n\n if not angle: return 0\n\n aa = 0.0\n ww = 0.0\n\n for a in angle:\n aa = angle_interpol(aa, ww, a, 1)\n ww += 1\n\n return aa\nRun Code Online (Sandbox Code Playgroud)\n\n如果您查看示例 {6\xc2\xb0, 50\xc2\xb0, 52\xc2\xb0, 54\xc2\xb0, 60\xc2\xb0, 250\xc2\xb0},您会注意到所有点都位于 250\xc2\xb0(或 -110\xc2\xb0)和 70\xc2\xb0 之间的同一个半圆上。使用所提出的平均方法,平均角度为 18.67\xc2\xb0。这也是 {6, 50, 52, 54, 60, -110} 的线性平均值,看起来很合理。中位数将在 50 到 52 之间。离群值仍然是 250\xc2\xb0 处的角度,但如果您来自 -110\xc2\xb0,则它比来自 250\xc2\xb0 更接近平均值。
\n\n另一个例子是{0\xc2\xb0, 0\xc2\xb0, 90\xc2\xb0}。矢量方法计算atan(0.5),即平均值约为 26.6\xc2\xb0。所提出的方法将 30\xc2\xb0 确定为平均值。
仅当您的数据未均匀分布在可行的角度范围内时,计算圆形平均值才有意义。如果角度相互抵消,则反正切方法具有奇点;上面提出的方法只会产生垃圾。
\n| 归档时间: |
|
| 查看次数: |
1963 次 |
| 最近记录: |