我有以下代码:
import itertools
import numpy as np
t = np.random.rand(3,3,3)
def foo(T):
res = np.zeros((3,3,3))
for a in range(3):
for b in range(3):
for c in range(3):
idx = [a,b,c]
combinations = list(itertools.permutations(idx, len(idx)))
idx_arrays = tuple(np.array(idx) for idx in zip(*combinations))
res[a, b, c] = (1.0/len(combinations))*np.sum(T[idx_arrays])
return res
sol = foo(t)
上面的代码应该相当于这样做:
for a in range(3):
for b in range(3):
for c in range(3):
res2[a,b,c] = (1.0/6)*(
t[a,b,c]
+ t[a,c,b]
+ t[b,a,c]
+ t[b,c,a]
+ t[c, a, b]
+ t[c,b,a]
)
为了使代码更快,我想替换外部的for loops
。这可以做到吗?理想情况下,这应该在不使用numpy的einsum
方法的情况下实现。
4条答案
按热度按时间kx5bkwkv1#
您可以通过不进行重复计算来开始改进:
zbwhf8kr2#
一行代码,使用
np.transpose
进行向量化:如果你想要比3更高的维度,这些
3
可以被改变或功能化import numpy as np from itertools import permutations as perm
nzrxty8p3#
我不知道这是否比3个嵌套的for循环快。无论如何,你可以试试这个:
这里,我不是使用
3 nested for loops
,而是从元组(0, 0, 0, 1, 1, 1, 2, 2, 2)
创建3 elements
的unique permutations
。42fyovps4#
这个解决方案怎么样?
简而言之,您需要修改
np.indices
的输出以生成idx_arrays。然后使用高级索引对原始数组中的值求和,再除以排列数。最后,将结果重新整形为3x3x3数组。此代码产生与原始代码相同的结果,但通过利用NumPy的向量化操作的功能,以更有效的方式产生。
在我的机器上: