Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/oop/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Algorithm 如何计算一组角度的中值?_Algorithm_Math_Geometry_Median - Fatal编程技术网

Algorithm 如何计算一组角度的中值?

Algorithm 如何计算一组角度的中值?,algorithm,math,geometry,median,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 me

我有一个角度列表,希望去掉异常值。我的第一个想法是计算中位数。不幸的是,存在“环绕”问题。我不知道有什么“正确”的方法来定义一组角度(或时钟位置)的中值

我的想法是首先计算平均值,然后用它来打破另一侧的圆圈

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
这是一个好方法,还是有更好的方法我不知道


有些相关:显示了计算角度平均值的方法。

您可以使用您链接的问题中显示的方法:将平均值计算为角度的累积单位向量的角度。在我看来,这种方法不太适合大型向量集

还有另一种方法可以使用加权插值。它不需要任何三角函数,这意味着您可以使用以度为单位的数据,而无需将它们转换为弧度

在这种方法中,所有角度必须介于0°和360°之间。如果它们位于外部,则必须将其置于该范围内,例如,-5°变为355°。然后进行两两加权平均,当角度差大于半圆时调整角度,以便始终在角度之间的较短圆弧上移动。求平均值后,所得角度将处于0°到360°的范围内

def angle_interpol(a1, w1, a2, w2):
    """Weighted avarage of two angles a1, a2 with weights w1, w2

    diff = a2 - a1        
    if diff > 180: a1 += 360
    elif diff < -180: a1 -= 360

    aa = (w1 * a1 + w2 * a2) / (w1 + w2)

    if aa > 360: aa -= 360
    elif aa < 0: aa += 360

    return aa

def angle_mean(angle):    
    """Unweighted average of a list of angles"""

    if not angle: return 0

    aa = 0.0
    ww = 0.0

    for a in angle:
        aa = angle_interpol(aa, ww, a, 1)
        ww += 1

    return aa
国际刑警组织定义角度(a1、w1、a2、w2): “两个角度a1、a2的加权平均值,加权为w1、w2 差异=a2-a1 如果差异>180:a1+=360 elif差值<-180:a1-=360 aa=(w1*a1+w2*a2)/(w1+w2) 如果aa>360:aa-=360 elif aa<0:aa+=360 返回aa def角度_平均值(角度): “角度列表的未加权平均值” 如果不是角度:返回0 aa=0.0 ww=0.0 对于内斜角: aa=国际刑警组织(aa,ww,a,1) ww+=1 返回aa 如果你看一下你的例子{6°、50°、52°、54°、60°、250°},你会注意到所有点都位于250°(或-110°)和70°之间的同一个半圆上。使用建议的Avarge方法,平均角度为18.67°。这也是{6,50,52,54,60,-110}的线性平均值,这似乎是合理的。中位数将在50和52之间。异常值仍然是250°的角度,但如果从-110°来,则比从250°来时更接近平均值

另一个例子是{0°、0°、90°}。矢量法计算出
atan(0.5)
,即约26.6°为平均值。建议的方法确定30°为平均值


只有当数据在可行角度范围内分布不均匀时,计算循环平均值才有意义。如果角度相互抵消,则arctan方法具有奇点;上述方法只会产生垃圾。

要获得一组数字的中值,请对它们进行排序,然后取中间的一个。也就是说,如果按排序顺序有7个数字,中位数是第3个数字

对角度也可以这样做,但结果没有什么意义,因为当你有多个角度时,“第一个角度”的概念没有很好的定义


要定义第一个角度,您可以对角度进行排序,并找到连续角度之间的最大间隙。两个角度之间最大间隙旁边的角度直观地感觉是“第一个”角度的最佳候选角度。

我相信以下方法是有意义的:

中位数是到所有输入点的距离之和最小的点(对于奇数个输入点,两个输入点之间会有一个完整的范围,因此通常取该范围的中间值).对于周期性角度,两个方向之间的距离应为两个可能方向中的最小值,即0和pi之间的距离


由于最小值是在一个输入点上实现的(或者如前所述,在奇数情况下是两个连续的点),因此对于n个角度有一个明显的O(n^2)算法。这似乎可以改进为O(n logn)通过对角度进行排序,计算第一个角度的距离总和,并通过跟踪列表中“对极”的位置来更新每个连续角度的距离总和“底角的角度正在下降。

这不是真正的编程问题。也许math.stackexchange.com是一个更好的提问场所。同样值得一提的是,这个问题是否有意义,以及是否有其他东西比中值更有意义。我可以想象,虽然你会得到类似的问题,为计算出你的平均数。对于角度1,2,3,你可以得到一个简单的平均值2。对于359,0,1,你可能会得到120的平均值,这可能不是你想要的。@Chris:检查关于讨论的其他答案的平均值,例如:355,0,90将产生25度。关于数学交换,你可能是对的。因为我必须对它进行编程,所以我想先在这里问一下如果你想在得到答案后如何实现它,那么这绝对是一个好去处。我怀疑这是程序员很少遇到的边缘情况,但数学家可能会遇到更多(或至少一些)。