将python代码矢量化为numpy

时间:2017-12-28 19:42:32

标签: python numpy vectorization

我有以下代码段(用于霍夫圆转换):

for r in range(1, 11):
    for t in range(0, 360):
        trad = np.deg2rad(t)

        b = x - r * np.cos(trad)
        a = y - r * np.sin(trad)

        b = np.floor(b).astype('int')
        a = np.floor(a).astype('int')

        A[a, b, r-1] += 1

其中A是形状(height, width, 10)的3D数组,和 heightwidth表示给定图片的大小。 我的目标是将代码段专门转换为numpy代码。

我的尝试是这样的:

arr_r = np.arange(1, 11)
arr_t = np.deg2rad(np.arange(0, 360))

arr_cos_t = np.cos(arr_t)
arr_sin_t = np.sin(arr_t)

arr_rcos = arr_r[..., np.newaxis] * arr_cos_t[np.newaxis, ...]
arr_rsin = arr_r[..., np.newaxis] * arr_sin_t[np.newaxis, ...]

arr_a = (y - arr_rsin).flatten().astype('int')
arr_b = (x - arr_rcos).flatten().astype('int')

xy是两个标量值。

我在转换增量部分时遇到问题:A[a,b,r] += 1。我想到了这一点:A[a,b,r]计算对(a,b,r)的出现次数,因此一个线索是使用笛卡尔积(但数组太大)。

我可以使用的任何提示或技巧吗?

非常感谢!

修改:填写A后,我需要(a,b,r)作为argmax(A)。元组(a,b,r)标识一个圆圈,其值A代表置信度值。所以我想要A中具有最高值的元组。这是Hough circle transform的投票算法的一部分:find circle parameter with unknown radius

2 个答案:

答案 0 :(得分:3)

方法#1

这是利用broadcasting获取计数并更新a的一种方式(假设在中间步骤中计算的bd0,d1,d2 = A.shape arr_r = np.arange(1, 11) arr_t = np.deg2rad(np.arange(0, 360)) arr_b = np.floor(x - arr_r[:,None] * np.cos(arr_t)).astype('int') arr_a = np.floor(y - arr_r[:,None] * np.sin(arr_t)).astype('int') idx = (arr_a*d1*d2) + (arr_b * d2) + (arr_r-1)[:,None] A.flat[:idx.max()+1] += np.bincount(idx.ravel()) # OR A.flat += np.bincount(idx.ravel(), minlength=A.size) 值为正一些) -

bincount

方法#2

或者,我们可以避免approach #1替换idx.ravel().sort() idx.shape = (-1) grp_idx = np.flatnonzero(np.concatenate(([True], idx[1:]!=idx[:-1],[True]))) A.flat[idx[grp_idx[:-1]]] += np.diff(grp_idx) 中的最后一步,就像这样 -

numexpr

使用import numexpr as ne arr_r2D = arr_r[:,None] arr_b = ne.evaluate('floor(x - arr_r2D * cos(arr_t))').astype(int) arr_a = ne.evaluate('floor(y - arr_r2D * sin(arr_t))').astype(int)

进行改进

我们还可以利用numexpr module进行更快的正弦,余弦计算,就像这样 -

datasheet = d
d$author = name of the study
d$number = study size (number of patients)
d$treat = number of treatments
d$hr_l = lower CI
d$hr_u = upper CI

答案 1 :(得分:2)

np.add(np.array([arr_a,arr_b,10]),1)