繁体   English   中英

在 numpy 中计算质心

[英]Compute center-of-mass in numpy

我正在寻找一种有效的方法来使用原生 python 和numpy计算二维numpy阵列的质心。 scipy.ndimage.measurements.center_of_mass可以完成这项工作,但我只能使用 numpy)

# sample data
a = np.array([[0, 0, 0],
              [0, 4, 4],
              [0, 0, 0]])

center_of_mass(a)
>>> (1., 1.5) # expected output

(scipy.ndimage.measurements.center_of_mass 完成这项工作,但我只能使用 numpy)

然后听起来是时候阅读源代码了 阅读后,对我而言,它看起来应该符合您的限制(仅使用 numpy ),因为它显然仅使用 python 内置插件和numpy 需要使用numpy.sum的替换sum 编辑:根据@Ricoter 的评论添加了替换sum的注释。

质心是sum(mi * xi)/msum(mi * yi)/m其中mi是质量(= 数组的元素), xiyi是坐标(数组的索引)。 m是总质量,即sum(mi)

a = np.array([[0,1,2],[3,4,5]])示例:

mi*ximi*yi我们通过将质量(即数组)与从mgrid获得的坐标网格相乘得到:

a * np.mgrid[0:a.shape[0], 0:a.shape[1]]

这使

array([[[ 0,  0,  0],
        [ 3,  4,  5]],

       [[ 0,  1,  4],
        [ 0,  4, 10]]])

其中上半部分为mi*yi下半部分为mi*xi ,其总和为

(a * np.mgrid[0:a.shape[0], 0:a.shape[1]]).sum(1).sum(1)

这给出了array([12, 19])

将其除以总和a.sum()我们得到array([0.8, 1.26666667])的最终结果。

综上所述,我们有:

(a * np.mgrid[0:a.shape[0], 0:a.shape[1]]).sum(1).sum(1)/a.sum()

Scipy 执行相同的操作,但使用开放网格和广播而不是完整(密集)网格,因此对于较大的 arrays 更快,因为它不需要为媒体查找器结果分配 ZCD69B4957F06CD818D7ZBF3D61980E29。

一个更便宜的解决方案。 memory 和使用矩阵乘法的计算时间:

import numpy as np


def center_of_mass(array: np.ndarray):
    total = array.sum()
    # alternatively with np.arange as well
    x_coord = (array.sum(axis=1) @ range(array.shape[0])) / total
    y_coord = (array.sum(axis=0) @ range(array.shape[1])) / total
    return x_coord, y_coord


a = np.asarray([[0, 0, 0],
                [0, 4, 4],
                [0, 0, 0]])

b = np.asarray([[0, 1, 2],
                [3, 4, 5]])

print(center_of_mass(a)) # (1.0, 1.5)
print(center_of_mass(b)) # (0.8, 1.2666666666666666)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM