python - 加快矩阵中每个 x,y 点的角度计算

标签 python performance numpy scipy vectorization

我有一个 3-d Numpy 数组 flow 如下:

flow = np.random.uniform(low=-1.0, high=1.0, size=(720,1280,2))
# Suppose flow[0] are x-coordinates. flow[1] are y-coordinates.

需要计算每个 x,y 点的角度。以下是我的实现方式:

def calcAngle(a):
    assert(len(a) == 2)
    (x, y) = a
    # angle_deg = 0
    angle_deg = np.angle(x + y * 1j, deg=True)
    return angle_deg

fangle = np.apply_along_axis(calcAngle, axis=2, arr=flow) 
# The above statement takes 14.0389318466 to execute

在我的 Macbook Pro 上执行每个点的角度计算需要 14.0389318466 秒

有没有一种方法可以加快速度,可能是通过使用一些矩阵运算,而不是一次处理一个像素。

最佳答案

您可以使用 numpy.arctan2()获取以弧度为单位的角度,然后使用 numpy.rad2deg() 转换为度数:

fangle = np.rad2deg(np.arctan2(flow[:,:,1], flow[:,:,0]))

在我的电脑上,这比 Divakar 的版本快一点:

In [17]: %timeit np.angle(flow[...,0] + flow[...,1] * 1j, deg=True)
10 loops, best of 3: 44.5 ms per loop

In [18]: %timeit np.rad2deg(np.arctan2(flow[:,:,1], flow[:,:,0]))
10 loops, best of 3: 35.4 ms per loop

使用 np.angle() 的一种更有效的方法是创建一个复杂的 flow View 。如果 flow 是类型为 np.float64 且形状为 (m, n, 2) 的数组,则 flow.view(np .complex128)[:,:,0] 将是 np.complex128 类型的数组,形状为 (m, n):

fangle = np.angle(flow.view(np.complex128)[:,:,0], deg=True)

这似乎比使用 arctan2 后跟 rad2deg 快一点点(但差异并不远高于 timeit 的测量噪音):

In [47]: %timeit np.angle(flow.view(np.complex128)[:,:,0], deg=True)
10 loops, best of 3: 35 ms per loop

请注意,如果 flow 创建为某个其他数组的转置,或者使用大于 1 的步长创建为另一个数组的切片,则这可能不起作用。

关于python - 加快矩阵中每个 x,y 点的角度计算,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45048478/

相关文章:

python - SKLearn 朴素贝叶斯 : add feature after tfidf vectorization

javascript - Python索引错误列表索引超出范围

python - Numpy/Python : why is integer division slowest? 中基本数学运算的速度

python - PIL 图像到阵列和返回

python - matplotlib boxplot 绘制 < > 大于和小于某个值

python - 从 Pandas 数据框中删除带有空列表的行

performance - Powershell在4.0环境下如何加速启动?

php - 如何在PHP中批量更新插入mongodb?

python - 使用不同的权重创建堆叠的 2D 直方图

python - 无法读取搜索索引