我试图避免使用numpy数组的for循环。
如果我的代码如下所示:
psimaps = [np.zeros((10,10)) for i in range(len(features)-1)]
for k in range(len(features)-1):
if k != len(features)-2:
psimaps[k] = np.reshape(np.sum(featureParams*features[k], axis=1), (10,1)) + transitiveParams
else:
psimaps[k] = np.reshape(np.sum(featureParams*features[k], axis=1), (10,1)) + (np.sum(featureParams * features[k+1], axis=1)) + transitiveParams
return psimaps
如何在没有for循环的情况下将其更改为列表表示以执行此操作?谢谢。
我添加了原始代码。基本上,我正在从两个阵列生成新的阵列计算。
答案 0 :(得分:3)
基本上您需要做的就是将features
数组广播到Params
数组。这可以通过在features
末尾插入两个新轴来完成(如果Params
数组不是2d,则更多)。请注意,我使用了keepdims
而不是总和之后的重塑。
psimaps = np.sum(featureParams*features[..., None, None], axis=2, keepdims=True) + transitiveParams
执行上述操作后,您必须将最后两行添加到一起,然后删除最后一行,因为您有一个奇怪的循环结束:
psimaps[-2] += psimaps[-1] - transitiveParams
psimaps = psimaps[:-1]
顺便说一下,在我理解它之前,我首先必须简化原始循环。我会在这里留下我的简化版本:
伪造数据(以及我对形状的假设)
size = 30
features = np.random.rand(50)
transitiveParams = np.random.rand(size, size)
featureParams = np.random.rand(size, size)
OP的原始代码
psimaps_OP = [np.zeros((size,size)) for i in range(len(features)-1)]
for k in range(len(features)-1):
if k != len(features)-2:
psimaps_OP[k] = np.reshape(np.sum(featureParams*features[k], axis=1), (size,1)) + transitiveParams
else:
psimaps_OP[k] = np.reshape(np.sum(featureParams*features[k], axis=1), (size,1)) + (np.sum(featureParams * features[k+1], axis=1)) + transitiveParams
简化为:
psimaps_simp = np.zeros((len(features)-1, size, size))
for k in range(len(features)-1):
psimaps_simp[k] = np.sum(featureParams*features[k], axis=1, keepdims=True) + transitiveParams
psimaps_simp[-1] += np.sum(featureParams*features[-1], axis=1)
list comp:
psimaps_comp = [np.sum(featureParams*features[k], axis=1, keepdims=True) + transitiveParams for k in xrange(len(features)-1)]
psimaps_comp[-1] += np.sum(featureParams*features[-1], axis=1)
矢量化:
psimaps_vec = np.sum(featureParams*features[..., None, None], axis=2, keepdims=True) + transitiveParams
psimaps_vec[-2] += psimaps_vec[-1] - transitiveParams
psimaps_vec = psimaps_vec[:-1]
接下来,检查以确保它们都给出相同的结果:
assert np.allclose(psimaps_simp, psimaps_OP), "simplification failed"
assert np.allclose(psimaps_simp, psimaps_vec), "vectorization failed"
最后,时间:
#OP
100 loops, best of 3: 1.99 ms per loop
#simplified:
1000 loops, best of 3: 1.94 ms per loop
#list comp:
1000 loops, best of 3: 1.63 ms per loop
#vectorised:
1000 loops, best of 3: 407 µs per loop
答案 1 :(得分:0)
如果初始化不重要,也许你可以这样做:
psimaps = [ featureParams + transitiveParams for k in xrange(1,10)]
对于每个k,将执行sum featureParams + transitiveParams。