首页 > 解决方案 > 如何加快敏感性分析?

问题描述

我必须处理需要加快的敏感性分析。数据在一个 numpy 数组中给出,我们称之为它AAgot shape(M, N)其中M是数据点N的数量,是每个数据点所包含的属性数,以及应计算分析的属性数。为简单起见,我们假设M=2, N=4. 有类似M=1+e9的想法。反正。让a_{mn}成为 的一个元素A。应该f(a_{m1},a_{m2}, a_{m3}, a_{m4}) = a_{m1} - a_{m2} - ( a_{m3} * a_{m4} )对每一行的函数计算进行分析,从而f(A)得到数组B形状(M,1)b_m的一个元素也是如此B

想要创建包含每个元素的灵敏度的数组E形状。例如元素(M, N)Be: m=1 an n=2, e_{mn}= e_{12} = f(a_{11},a_{12}*(1-i), a_{13}, a_{14}) - b_1

现在搜索每个元素的灵敏度B。让敏感性i成为i=0.05。首先,我计算了一个(M, N)包含所有元素及其变化的形状数组。我们称之为C = B * i,其中*是逐元素乘法。之后,创建D,我循环遍历数组中的每个元素。最后减去B得到E。我想那太贵了,而且很俗气。这就是为什么它不适用于大量数据的原因。这是我得到的:

import numpy as np

A = np.array([
    [2., 2., 100., 0.02],
    [4., 2., 100., 0.02]
])

def f_from_array(data):
    att_1 = data[:, 0]
    att_2 = data[:, 1]
    att_3 = data[:, 2]
    att_4 = data[:, 3]
    return ((att_1 - att_2) - (att_3 * att_4)).reshape(-1, 1)

def f_from_list(data):
    att_1 = data[0]
    att_2 = data[1]
    att_3 = data[2]
    att_4 = data[3]
    return ((att_1 - att_2) - (att_3 * att_4)).reshape(-1, 1)

B = f_from_array(A)

# B = np.array([
#     [-2.],
#     [0.]
# ])

i = 0.05
C = A * i
A_copy = A * 1
D = np.zeros(A.shape)
for m in range(A.shape[0]):
    for n in range(A.shape[1]):
        A_copy[m][n] -= C[m][n]
        D[m][n] = f_from_list(A_copy[m])
        A_copy = A * 1

E = D - B
E = np.sqrt(E**2)

输出:

E = np.array([
    [0.1, 0.1, 0.1, 0.1],
    [0.2, 0.1, 0.1, 0.1]
])

标签: pythonarraysnumpy

解决方案


显然,代码的问题部分是嵌套的 for 循环。这里可以做很多事情,并且可能完全消除循环。

但是如果没有过多考虑代码的作用,最明显的时间杀手可能是您在每次循环迭代期间创建整个数组的副本。通过仅恢复一个元素而不是整个数组来消除这种情况。

代替

A_copy = A * 1

在循环内,执行以下操作:

A_copy[m, n] = A[m, n]

(顺便说一句:使用逗号进行索引比使用多于一对括号进行多步索引要快一些,但对于您的情况可能无关紧要。)


推荐阅读