【问题标题】:Vectorize numpy assignment向量化numpy分配
【发布时间】:2014-05-21 14:42:12
【问题描述】:

我通过在其他 numpy 数组中查找值来为 numpy 数组赋值。这些数组可能具有不同的索引。这是一个例子:

import numpy as np
A=1; B=2; C=3; D=4; E=5
X = np.random.normal(0,1,(A,B,C,E))
Y = np.random.normal(0,1,(A,B,D))
Z = np.random.normal(0,1,(A,C))
Result = np.zeros((A,B,C,D,E))
for a in range(A):
    for b in range(B):
        for c in range(C):
            for d in range(D):
                for e in range(E):
                    Result[a,b,c,d,e] = Z[a,c] + Y[a,b,d] + X[a,b,c,e]

优化此代码的最佳方法是什么?我可以使用 Result[a,b,c,d,:] = Z[a,c] + Y[a,b,d] + X[a,b,c,:] 删除 E for 循环。但是那么如何删除其余的循环呢?我还认为我可以在分配之前操纵 X、Y、Z,以便它可以轻松地与 Result 的维度合并。必须有更优雅的方式。感谢您的提示。

【问题讨论】:

  • 这更像是一个 codereview.stackexchange.com 问题。你应该把它移植到那里,看看人们想出了什么优化技巧。
  • 虽然从技术上讲是一个代码优化问题,但在 SO 中经常会问这样的问题(如何在 numpy 中进行矢量化?)。这真的是一个“如何做”的问题。

标签: python arrays numpy


【解决方案1】:

这是一种方法:

Result = Z[:,None,:,None,None] + Y[:,:,None,:,None] + X[:,:,:,None,:]

为了生成这个矢量化版本,我所做的只是将各种索引替换为 XYZ,并使用完整的 a,b,c,d,e 样式索引,在找到缺失索引的地方插入 None。比如Y[a,b,d]变成Y[a,b,None,d,None],向量化成Y[:,:,None,:,None]

在 numpy 中,None 的索引告诉数组假装它有一个额外的轴。这不会改变数组的大小,但会改变操作的广播方式,这正是我们需要的。查看numpy broadcasting docs 了解更多信息。

【讨论】:

  • 很好的答案。如果您还可以添加一个链接到一些描述由此带来的广播变化的文档,那就太好了。
  • 使用我的参数快 75 倍...谢谢!
猜你喜欢
  • 2017-04-04
  • 1970-01-01
  • 2017-03-28
  • 1970-01-01
  • 2021-08-13
  • 1970-01-01
  • 2015-07-27
  • 2017-03-30
  • 2021-05-31
相关资源
最近更新 更多