簡體   English   中英

在沒有numpy的情況下在python中計算一組坐標元組的質心的最快方法

[英]Fastest way to calculate the centroid of a set of coordinate tuples in python without numpy

我一直在研究一個對時間非常敏感的項目(不幸的是它必須在 python 中),廣泛使用的函數之一是計算 (x, y) 元組列表的質心的函數。 為了顯示:

def centroid(*points):
    x_coords = [p[0] for p in points]
    y_coords = [p[1] for p in points]
    _len = len(points)
    centroid_x = sum(x_coords)/_len
    centroid_y = sum(y_coords)/_len
    return [centroid_x, centroid_y]

在哪里

>>> centroid((0, 0), (10, 0), (10, 10), (0, 10))
[5, 5]

這個函數運行得相當快,上面的例子在我的系統上平均需要 1.49e-05 秒完成,但我正在尋找計算質心的最快方法。 你有什么想法?

我的其他解決方案之一是執行以下操作(其中l是元組列表):

map(len(l).__rtruediv__, map(sum, zip(*l)))

它在 1.01e-05 和 9.6e-06 秒之間運行,但不幸的是轉換為列表(通過在list( ... )包圍整個語句)幾乎使計算時間加倍

編輯:歡迎在純 python 中提出建議,但不是 numpy。

EDIT2:剛剛發現如果為元組列表的長度保留一個單獨的變量,那么我上面的map實現可以在 9.2e-06 秒內可靠地運行,但是仍然存在轉換回列表的問題。

編輯3:

現在我只接受純 python 的答案,而不是 numpy 的答案(抱歉那些已經用 numpy 回答的人!)

import numpy as np

data = np.random.randint(0, 10, size=(100000, 2))

這里很快

def centeroidnp(arr):
    length = arr.shape[0]
    sum_x = np.sum(arr[:, 0])
    sum_y = np.sum(arr[:, 1])
    return sum_x/length, sum_y/length

%timeit centeroidnp(data)
10000 loops, best of 3: 181 µs per loop

令人驚訝的是,這要慢得多:

%timeit data.mean(axis=0)
1000 loops, best of 3: 1.75 ms per loop

numpy 對我來說似乎很快......

為了完整性:

def centeroidpython(data):
    x, y = zip(*data)
    l = len(x)
    return sum(x) / l, sum(y) / l
#take the data conversion out to be fair!
data = list(tuple(i) for i in data)

%timeit centeroidpython(data)
10 loops, best of 3: 57 ms per loop

在笛卡爾坐標中,質心只是分量的平均值:

data = ((0,0), (1,1), (2,2))
np.mean(data, axis=0)
>>> array([1., 1.])

為了完整起見,我修改了 Retozi 的函數,使其接受任何維度的向量:

def centeroidnp(arr):
    length, dim = arr.shape
    return np.array([np.sum(arr[:, i])/length for i in range(dim)])

這是一個天真的 numpy 實現,我不能在這里計時,所以我想知道它是怎么做的:

import numpy as np

arr = np.asarray(points)
length = arr.shape[0]
sum_x = np.sum(arr[:, 0])
sum_y = np.sum(arr[:, 1])
return sum_x / length, sum_y / length

您將點作為單獨的參數傳遞給centroid() ,然后將它們放入帶有*points的單個元組中。 只傳遞帶有點的列表或迭代器會更快。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM