有没有更快的方法重复一段代码x次并取平均值?

时间:2018-02-16 12:26:47

标签: python numpy

从:

开始
    a,b=np.ogrid[0:n+1:1,0:n+1:1]
    B=np.exp(1j*(np.pi/3)*np.abs(a-b))
    B[z,b] = np.exp(1j * (np.pi/3) * np.abs(z - b +x))
    B[a,z] = np.exp(1j * (np.pi/3) * np.abs(a - z +x))
    B[diag,diag]=1-1j/np.sqrt(3)

这会产生一个n * n网格作为矩阵。

n只是选择用于表示索引的数字,即a * b矩阵,其中a和b都达到n。

当z是常数时,我选择用B [z,b]和B [a,z]公式替换行和列。 (基本上是相同的公式,但在np.abs(a-b)中添加了一个小数字)

矩阵的对角线由底线给出:

B[diag,diag]=1-1j/np.sqrt(3)

其中,

diag=np.arange(n+1)

我想重复这段代码50次,其中唯一改变的是x,所以我最终会得到50个版本的B np.ogrid。 x是每次在-0.8和0.8之间随机生成的数字。

x=np.random.uniform(-0.8,0.8)

我希望每次生成50个随机值为x的B版本,并使用以下定义取50个版本的B的几何平均值:

def geo_mean(y):
   y = np.asarray(y)
   return np.prod(y ** (1.0 / y.shape[0]), axis=-1)

我试图将B设置为某个索引的函数,然后使用for _ in range():循环,这不起作用。除了复制和粘贴块50次,并将每个块表示为B1,B2,B3等;我想不出另一种解决方法。

编辑:

我现在正在使用给定解决方案的一部分,以便清楚地显示我正在寻找的内容:

#A matrix with 50 random values between -0.8 and 0.8 to be used in the loop
X=np.random.uniform(-0.8,0.8, (50,1))
#constructing the base array before modification by random x values in position z
 a,b = np.ogrid[0:n+1:1,0:n+1:1]
 B = np.exp(1j * ( np.pi / 3) * np.abs( a - b ))
 B[diag,diag] = 1 - 1j / np.sqrt(3)
#list to store all modified arrays
 randomarrays = []
 for i in range( 0,50 ):
#copy array and modify it
    Bnew = np.copy( B )
    Bnew[z, b] = np.exp( 1j * ( np.pi / 3 ) * np.abs(z - b + X[i]))
    Bnew[a, z] = np.exp( 1j * ( np.pi / 3 ) * np.abs(a - z + X[i]))
    randomarrays.append(Bnew)

 Bstack = np.dstack(randomarrays)
#calculate the geometric mean value along the axis that was the row in 2D arrays
 B0 = geo_mean(Bstack)

从这个例子中,i的每次迭代使用相同的X值,我似乎无法获得一种方法来获取i的每个新循环以使用矩阵中的下一个值X。我不确定python中的++动作,我知道它在python中不起作用,我只是不知道如何使用python等效。我想要一个循环使用X的值,然后下一个循环使用下一个值,依此类推,以便我可以dstack最后的所有矩阵并找到{{1}对于堆叠矩阵中的每个元素。

2 个答案:

答案 0 :(得分:2)

我认为在接近您的问题时,您应该更多地依赖于numpy功能。我自己并不是一个笨拙的专家,因此肯定有改进的余地:

from scipy.stats import gmean

n = 2
z = 1
a = np.arange(n + 1).reshape(1, n + 1)
#constructing the base array before modification by random x values in position z
B = np.exp(1j * (np.pi / 3) * np.abs(a - a.T))
B[a, a] = 1 - 1j / np.sqrt(3)
#list to store all modified arrays
random_arrays = []
for _ in range(50):
    #generate random x value
    x=np.random.uniform(-0.8, 0.8)
    #copy array and modify it
    B_new = np.copy(B)
    B_new[z, a] = np.exp(1j * (np.pi / 3) * np.abs(z - a + x))
    B_new[a, z] = np.exp(1j * (np.pi / 3) * np.abs(a - z + x))
    random_arrays.append(B_new)

#store all B arrays as a 3D array
B_stack = np.stack(random_arrays)
#calculate the geometric mean value along the axis that was the row in 2D arrays
geom_mean_for_rows = gmean(B_stack, axis = 2)

它使用scipy.stats模块中的几何平均函数来为此计算提供矢量化方法。

答案 1 :(得分:2)

一种行人方式是使用列表理解或生成器表达式:

sed 's/\(||o||[^|]*\)//1' infile

但在你的具体例子中,我们可以做得更好; 使用标识>>> def f(n, z, x): ... diag = np.arange(n+1) ... a,b=np.ogrid[0:n+1:1,0:n+1:1] ... B=np.exp(1j*(np.pi/3)*np.abs(a-b)) ... B[z,b] = np.exp(1j * (np.pi/3) * np.abs(z - b +x)) ... B[a,z] = np.exp(1j * (np.pi/3) * np.abs(a - z +x)) ... B[diag,diag]=1-1j/np.sqrt(3) ... return B ... >>> X = np.random.uniform(-0.8, 0.8, (10,)) >>> np.prod((*map(np.power, map(f, 10*(4,), 10*(2,), X), 10 * (1/10,)),), axis=0) ,我们可以将取幂后的几何平均值转换为指数前的算术平均值。需要注意一点,因为复杂的第n个根的多值性出现在几何平均值中。在下面的代码中,我们将出现的角度标准化为-pi,pi范围,以便始终与第n个根相同的分支。

另请注意,您提供的exp(a) x exp(b) = exp(a + b)功能绝对是错误的。它没有通过基本的健全性检查,即取同一件事的副本的平均值应该返回相同的东西。我提供了更好的版本。它仍然不完美,但我认为实际上没有完美的解决方案,因为复杂根的非唯一性。

因此我建议在取幂之前取平均值。只要你的随机扩散小于pi,就可以得到定义明确的平均过程,其平均值实际上接近样本

geo_mean