python - 计算一半对称 numpy 矩阵的更好方法?

标签 python numpy optimization matrix

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

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

返回:

array([[ 1.,  1.,  1.,  1.,  1.,  1.,  1.,  1.,  1.,  1.],
       [ 0.,  1.,  1.,  1.,  1.,  1.,  1.,  1.,  1.,  1.],
       [ 0.,  0.,  1.,  1.,  1.,  1.,  1.,  1.,  1.,  1.],
       [ 0.,  0.,  0.,  1.,  1.,  1.,  1.,  1.,  1.,  1.],
       [ 0.,  0.,  0.,  0.,  1.,  1.,  1.,  1.,  1.,  1.],
       [ 0.,  0.,  0.,  0.,  0.,  1.,  1.,  1.,  1.,  1.],
       [ 0.,  0.,  0.,  0.,  0.,  0.,  1.,  1.,  1.,  1.],
       [ 0.,  0.,  0.,  0.,  0.,  0.,  0.,  1.,  1.,  1.],
       [ 0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  1.,  1.],
       [ 0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  1.]])

很简单...

但是,当 Matrix 较大且计算量很大时: 嵌套 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()

基准测试 @unutbu test 下面的函数,针对 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

最佳答案

这是一个简单的实验,表明瓶颈更有可能是 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()

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

In [85]: %timeit test(SimpleFunction)
1000 loops, best of 3: 890 µs per loop

两次 timeit 运行除了被调用的函数不同之外是相同的。 当 funcSimpleFunction 时,填充 BigMatrix 不到 1 毫秒。 但是当 funcExpensiveFunction 时,填充 BigMatrix 需要 5 秒以上。

所以双 for-loop 可能不是瓶颈; ExpensiveFunction 是。您可以尝试使用您的实际代码来确定。如果确实证明 ExpensiveFunction 是瓶颈,那么您就不需要费心优化双循环,因为即使有更快的方法来填充 BigMatrix --即使您可以将时间成本降低到零——您(在上述情况下)最多也只能节省 890 us,而整个程序仍然需要 5 秒以上。

关于python - 计算一半对称 numpy 矩阵的更好方法?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30377220/

相关文章:

python - 如何将具有 numpy 数组值的 Pandas 系列转换为数据框

java - 增量共轭梯度算法

python - Matplotlib 具有相同类变量的多个动画

python - 检查元素是列表还是另一个对象

python - python中分类变量的knn插补

python - 颜色条中的结束刻度 - matplotlib

python - 如何从决策树的 x_train 预测位置获取叶子的节点号?

python - 不理解 NumPy loadtxt 中的转换器行为

php - MySQL fulltext/regexp/levenshtein 搜索优化

c++ - 私有(private)成员的常量访问器之间的比较