如何计算python中x,y坐标的质心

Mar*_*ger 3 python points coordinate-systems centroid

我有很多x,y坐标,我根据它们之间的距离聚集在一起.现在我想计算每个x,y坐标簇的质心量度.有没有办法做到这一点?

我的坐标格式为:

    coordinates_cluster = [[x1,x2,x3,...],[y1,y2,y3,...]]
Run Code Online (Sandbox Code Playgroud)

每个簇的最小长度为三个点,并且所有点都可以具有负x和y值.我希望有人可以帮助我.

最好,马丁

(我在Windows 7系统上使用带有canopy 1.1.1(32位)的python 2.7.)

XII*_*II_ 11

此处给出的公认答案不适用于典型的现实生活用例,在这些用例中,您想要计算由一组 (x,y) 顶点(又名多边形)定义的形状的质心。所以请原谅我回答一个大约 8 年前提出的问题,但它仍然在我的 SO 搜索中名列前茅,所以它可能也会出现在其他人身上。我并不是说在问题的具体情况下接受的答案是错误的,但我认为,大多数找到这个线程的人实际上是根据不同的定义来寻找质心的。

\n

质心未定义为顶点的算术平均值

\n

...这与普遍观点相反。\n我们必须承认,通常通过质心,我们认为 \xe2\x80\x9c 是图中所有点的算术平均位置。通俗地说,就是在这个点上,形状的切口可以完美地平衡在销钉\xe2\x80\x9d 的尖端上(引用维基百科\xe2\x80\x99s 在这里引用的实际文献)。请注意,这是图中的所有点,而不仅仅是顶点坐标的平均值。\n这正是如果您接受大多数 SO 答案就会出错的地方,这意味着质心是算术顶点的 x 和 y 坐标的平均值,并将其应用于您可能通过执行实验收集的现实生活数据。
\n描述你的形状的点的密度可能会沿着你的形状的线而变化。这只是所述方法的许多可能的限制之一。那么坐标的简单平均值肯定不是您想要的。我\xe2\x80\x99将用一个例子来说明这一点。

\n

例子

\n

多边形示例
\n这里我们看到一个由 8 个顶点组成的多边形。我们的直觉正确地告诉我们,我们可以在 (x,y)=(0,0) 处的销尖上平衡这个形状,使质心为 (0,0)。但在 (-1,1) 周围的区域中,我们用来描述该多边形的点/顶点的密度高于沿线的其他区域。现在,如果我们通过取顶点的平均值来计算质心,结果将被拉向高密度区域。
\n点 \xe2\x80\x9ccentroid poly\xe2\x80\x9c 对应于真正的质心。该点是通过实现此处描述的算法来计算的: https: //en.wikipedia.org/wiki/Centroid#Of_a_polygon(唯一的区别:它返回面积的绝对值)
\n它适用于由 x 和 y 坐标描述的图形N 个顶点,如 X = x_0, x_1, \xe2\x80\xa6, x_(N-1),Y 相同。该图形可以是任何多边形,只要它是非自相交的,并且顶点在发生的顺序。
\n这可用于计算例如 matplotlib 轮廓线的 \xe2\x80\x9creal\xe2\x80\x9d 质心。

\n

代码

\n

这是上面示例的代码以及所述算法的实现:

\n
import matplotlib.pyplot as plt\n\ndef centroid_poly(X, Y):\n    """https://en.wikipedia.org/wiki/Centroid#Of_a_polygon"""\n    N = len(X)\n    # minimal sanity check\n    if not (N == len(Y)): raise ValueError(\'X and Y must be same length.\')\n    elif N < 3: raise ValueError(\'At least 3 vertices must be passed.\')\n    sum_A, sum_Cx, sum_Cy = 0, 0, 0\n    last_iteration = N-1\n    # from 0 to N-1\n    for i in range(N):\n        if i != last_iteration:\n            shoelace = X[i]*Y[i+1] - X[i+1]*Y[i]\n            sum_A  += shoelace\n            sum_Cx += (X[i] + X[i+1]) * shoelace\n            sum_Cy += (Y[i] + Y[i+1]) * shoelace\n        else:\n            # N-1 case (last iteration): substitute i+1 -> 0\n            shoelace = X[i]*Y[0] - X[0]*Y[i]\n            sum_A  += shoelace\n            sum_Cx += (X[i] + X[0]) * shoelace\n            sum_Cy += (Y[i] + Y[0]) * shoelace\n    A  = 0.5 * sum_A\n    factor = 1 / (6*A)\n    Cx = factor * sum_Cx\n    Cy = factor * sum_Cy\n    # returning abs of A is the only difference to\n    # the algo from above link\n    return Cx, Cy, abs(A)\n\n# ********** example ***********\nX = [-1, -0.8,  -0.6,  1,   2,  1, -1,   -2]\nY = [ 1,    1,     1,  1, 0.5, -1, -1, -0.5]\n\nCx, Cy, A = centroid_poly(X, Y)\n\n# calculating centroid as shown by the accepted answer\nCx_accepted = sum(X)/len(X)\nCy_accepted = sum(Y)/len(Y)\n\nfig, ax = plt.subplots()\nax.scatter(X, Y, label=\'vertices\')\nax.scatter(Cx_accepted, Cy_accepted, label="mean of vertices")\nax.scatter(Cx, Cy, label=\'centroid poly\')\n\n# just so the line plot connects xy_(N-1) and xy_0\nX.append(X[0]), Y.append(Y[0])\nax.plot(X, Y, label=\'polygon\')\n\nax.legend(bbox_to_anchor=(1, 1))\nax.grid(), ax.set_aspect(\'equal\')\n
Run Code Online (Sandbox Code Playgroud)\n


Mar*_*ger 6

我意识到这并不难,但这里是用于计算x,y坐标的质心的代码:

    >>> c = [[1,4,-5],[3,-2,9]] # of the form [[x1,x2,x3],[y1,y2,y3]]
    >>> centroide = (sum(c[0])/len(c[0]),sum(c[1])/len(c[1]))

    >>> centroide
    (0, 3)
Run Code Online (Sandbox Code Playgroud)