计算对称纽比矩阵一半的更好方法?

2024-09-29 21:34:41 发布

您现在位置:Python中文网/ 问答频道 /正文

矩阵的每一个单元格都需要一个由昂贵函数计算的分数。矩阵是对称的,这是我能想到的填充每个单元格的最佳方法。在

num_cases = len(case_dictionary.keys())  # num_cases = 10
SmallMatrix = np.zeros((num_cases,num_cases))

for CasesX in range(0,num_cases):
    for CasesY in range(CasesX,num_cases):
        SmallMatrix[CasesX,CasesY] = 1

退货:

^{pr2}$

很简单。。。在

但是,当矩阵较大且计算成本较高时: 嵌套for循环是最有效的解决方案吗?在

num_cases = len(case_dictionary.keys())  # 100000
BigMatrix = np.zeros((num_cases,num_cases))

for CasesX in range(0,num_cases):
    for CasesY in range(CasesX,num_cases):
        BigMatrix[CasesX,CasesY] = ExpensiveFunction()

慢点。。。是因为我的功能,还是因为循环?在

编辑

一直在处理成对数据,所以我回去尝试使用@hpaulj解决方案。我没有足够的知识来理解为什么testUpper()更快?在

def testUpper(func):
    num_cases = 100
    BigMatrix = np.zeros((num_cases,num_cases))

    upper = np.triu_indices_from(BigMatrix)

    BigMatrix[upper] = ExpensiveFunction()

从下面对@unutbutest函数与numpy版本进行了对比:

In [8]: %timeit test(ExpensiveFunction)
        1 loops, best of 3: 11.1 s per loop

In [9]: %timeit testUpper(ExpensiveFunction)
        1000 loops, best of 3: 2.03 ms per loop

Tags: 函数inforlennpzerosrange矩阵
2条回答

下面是一个简单的实验,它表明瓶颈更有可能是ExpensiveFunction

import time

def SimpleFunction():
    return 1

def ExpensiveFunction():
    time.sleep(0.001)
    return 1

def test(func):
    num_cases = 100
    BigMatrix = np.zeros((num_cases,num_cases))

    for CasesX in range(0,num_cases):
        for CasesY in range(CasesX,num_cases):
            BigMatrix[CasesX,CasesY] = func()

^{pr2}$

除了被调用的函数外,它运行的两次时间是相同的。 当funcSimpleFunction时,填充{}所需时间少于1ms。 但是当func是{}时,填充{}会占用5s的时间

所以双for-loop可能不是瓶颈;ExpensiveFunction是。你可以尝试用你的实际代码来确保。如果结果证明ExpensiveFunction是瓶颈,那么您不必费心优化双循环,因为即使有一种更快的方法来填充{},即使您可以将时间成本削减为零,您(在上面的情况下)最多只节省{},而整个程序仍然需要5秒以上。在

我建议将“昂贵”的计算应用于矩阵的一半,然后使用symmetrize()函数使numpy数组对称,这应该以最小的时间开销

def symmetrize(a):
    return a + a.T - numpy.diag(a.diagonal())

相关问题 更多 >

    热门问题