【问题标题】:Optimizing numpy matrix operations (currently using a for loop)优化 numpy 矩阵运算(当前使用 for 循环)
【发布时间】:2014-08-02 19:30:09
【问题描述】:

我编写了一些代码来根据列表中的 n 个项目计算 n 个矩阵,然后在最后将所有矩阵相乘。

代码比较慢,想了解更多关于python优化的知识。我使用了分析工具并确定我的程序中的减速是这个矩阵乘法循环。

我想知道是否有人对我如何加快速度有任何建议,也许可以利用 Python / NumPy 中基于 C 的内置函数?

def my_matrix(x):

    # Initialise overall matrix as an identity matrix
    # | M_11 M_12 |
    # | M_21 M_22 |
    M = np.matrix([[1, 0],[0, 1]])

    for z in z_all:
        param1 = func1(z)
        param2 = func2(x, z)
        param3 = func3(x, z)

        M_11 = param1 + param2
        M_12 = param1 - param2
        M_21 = param1 * param2
        M_22 = param1 / param2

        # Multiply matrix with overall master matrix
        M = M * np.matrix([[M_11, M_12],[M_21, M_22]])
    return M

从一点背景阅读来看,函数调用的计算成本似乎很高,因此,为我的参数计算数组然后访问数组可能比每次在循环中评估函数更有效......例如

 param1s = funcs(z_all)
 param2s = funcs(x, z_all)
 etc

然后在for循环中:

for i, z in enumerate(z_all):
    param1 = params1[i]
    param2 = params2[i]
 etc.

这更快,但只有大约 10%,因为通过在循环中使用 param1 = params1[i] 进行数组访问所花费的时间抵消了更少的函数调用所节省的时间。

请问大家有什么推荐的吗?

【问题讨论】:

  • 您的任何参数/变量是否在整个循环中保持不变?如果是这种情况,您可以在循环之前定义它,从而避免反复运行该函数。

标签: python optimization numpy matrix matrix-multiplication


【解决方案1】:

您可以通过 M_11s = params1 + params2 等对 M_11, ... M_22 的计算进行矢量化处理。

这样你只需要在循环中进行矩阵乘法:

import numpy as np

...

# compute your 'params' over vectors of z-values
param1s = func1(z_all)
param2s = func2(x, z_all)
param3s = func3(x, z_all)  # you don't seem to be using this for anything...

# compute 'M_11, ... M_22'
M_11 = param1s + param2s
M_12 = param1s - param2s
M_21 = param1s * param2s
M_22 = param1s / param2s

# we construct a (2, 2, nz) array from these
M_all = np.array([[M_11, M_12], [M_21, M_22]])

# roll the 'nz' axis to the front so that its shape is (nz, 2, 2)
M_all = np.rollaxis(M_all, -1, 0)

# initialize output with the identity
M_out = np.eye(2)

# loop over each (2, 2) subarray in 'M_all', update the output with the
# corresponding dot product
for mm in M_all:
    M_out = M_out.dot(mm)

【讨论】:

  • 谢谢,速度提高了 3 倍!你能详细说明为什么这更快吗?一般来说,使用数组是否比使用矩阵更好,因为这里的 numpy 点积似乎等同于矩阵乘法。
  • 加速的主要原因是M_11, ... ,M_22的计算现在是矢量化的。对整个向量进行操作总是比索引单个元素更可取。在这里使用数组而不是矩阵的主要论点是数组可以具有任意等级,而矩阵的最大等级为 2。如果我使用矩阵,M_all 必须是(2, 2) 矩阵的列表而不是一个大批。有很多其他原因更喜欢数组而不是矩阵,see here
  • 谢谢,这是一个非常有帮助的回复。我实际上想计算 2D 参数空间的 M_out 。目前我循环遍历一个参数(我们称之为“时间”),并且对于时间数组中的每一次,我使用上面的代码来计算 M_out。我想知道这是否可以通过用一些向量操作替换 for 循环来进一步改进。我已经详细阐述并概括了我的问题,因为我相信这里过多的讨论可能会淡化这个问题和回应:stackoverflow.com/questions/25100046/…
猜你喜欢
  • 1970-01-01
  • 2022-08-13
  • 2022-01-01
  • 2015-10-02
  • 1970-01-01
  • 1970-01-01
  • 2018-05-28
  • 1970-01-01
  • 2013-12-21
相关资源
最近更新 更多