如何加快灵敏度分析?

时间:2019-04-09 15:36:16

标签: python arrays numpy

我必须处理需要加快速度的敏感性分析。数据以numpy数组形式给出,我们称其为AA的形状为(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_mB的元素。

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

现在在B上搜索每个元素的敏感性。令灵敏度ii=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]
])

1 个答案:

答案 0 :(得分:0)

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

但是无需过多考虑代码的作用,最明显的时间杀手可能是您在每次循环迭代期间创建整个数组的副本。只需还原一个元素而不是整个数组即可消除这种情况。

代替

A_copy = A * 1

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

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

(顺便说一句:用逗号索引比使用多于一对括号的多步骤索引要快一些,但对您而言可能并不重要。)