【问题标题】:Improving for loop speed for numpy.ndarray提高 numpy.ndarray 的循环速度
【发布时间】:2015-03-24 11:27:01
【问题描述】:

我正在尝试计算数据集中一元组的互信息。尝试执行此操作时,我试图提高循环遍历 numpy ndarray 的速度。我有以下代码,其中我使用已创建的具有 6018 行和 27721 列的矩阵“C”来计算 PMI 矩阵。任何想法如何提高 for 循环速度(目前需要将近 4 个小时才能运行)?我在其他一些关于使用 Cython 的文章中读到了,但是还有其他选择吗?在此先感谢您的帮助。

# MAKE MUTUAL INFO MATRIX, PMI
print "Creating mutual information matrix"
N = C.sum()
invN = 1/N  # replaced divide by N with multiply by invN in formula below
PMI = np.zeros((C.shape))
row, col = C.shape
for r in xrange(row):  # u
    for c in xrange(r):  # w
        if C[r,c]!=0:  # if they co-occur
            numerator = C[r,c]*invN  # getting number of reviews where u and w co-occur and multiply by invN (numerator)
            denominator = (sum(C[:,c])*invN) * (sum(C[r])*invN)
            pmi = log10(numerator*(1/denominator))
            PMI[r,c] = pmi
            PMI[c,r] = pmi

【问题讨论】:

    标签: python performance python-2.7 numpy


    【解决方案1】:

    如果您可以取消循环并利用 NumPy 的矢量化,您应该会获得更快的速度。

    我还没有尝试过,但是这样的东西应该可以工作:

    numerator = C * invN
    denominator = (np.sum(C, axis=0) * invN) * (np.sum(C, axis=1)[:,None] * invN)
    pmi = np.log10(numerator * (1 / denominator))
    

    请注意,numeratordenominatorpmi 都是值数组,而不是标量。

    另外,您可能必须以某种方式处理C == 0 案例:

    pmi = np.log10(numerator[numerator != 0] * (1 / denominator[numerator != 0]))
    

    正如 Blckknght 在 cmets 中指出的那样,您可以省略一些 invN 乘法:

    denominator = np.sum(C, axis=0) * np.sum(C, axis=1)[:,None] * invN
    pmi = np.log10(C * (1 / denominator))
    

    【讨论】:

    • 这也是我要建议的方法。我认为要使denominator 数组具有正确的尺寸,您需要更改其中一个总和的轴,也许使用像[:,None] 这样的切片)。此外,可能会忽略一堆 invN 乘法,因为它们大多倾向于在最后的除法中取消(我认为分母中还剩下一个因素)。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-08-01
    • 2014-07-27
    • 1970-01-01
    • 2017-10-06
    • 2014-01-20
    • 2017-01-28
    • 1970-01-01
    相关资源
    最近更新 更多