如何在numpy中对这个循环差异进行矢量化?

时间:2013-02-19 07:05:43

标签: python matlab numpy linear-algebra

我觉得应该有一种快速加速这段代码的方法。我认为答案是here,但我似乎无法以这种格式解决问题。我试图解决的根本问题是找到平行和垂直分量方面的明显差异,并创建这些差异的二维直方图。

out = np.zeros((len(rpbins)-1,len(pibins)-1))
tmp = np.zeros((len(x),2))
for i in xrange(len(x)):
    tmp[:,0] = x - x[i]
    tmp[:,1] = y - y[i]

    para = np.sum(tmp**2,axis=-1)**(1./2)
    perp = np.abs(z - z[i])

    H, _, _ = np.histogram2d(para, perp, bins=[rpbins, pibins])
    out += H

1 个答案:

答案 0 :(得分:3)

对这样的事情进行矢量化是很棘手的,因为要摆脱n元素上的循环,你必须构造一个(n, n)的数组,所以对于大输入,你可能会得到比用Python循环。但它可以做到:

mask = np.triu_indices(x.shape[0], 1)
para = np.sqrt((x[:, None] - x)**2 + (y[:, None] - y)**2)
perp = np.abs(z[:, None] - z)
hist, _, _ = np.histogram2d(para[mask], perp[mask], bins=[rpbins, pibins])

mask是为了避免两次计算每个距离。我还将对角线偏移设置为1,以避免在直方图中包含每个点与{1}}的距离。但是,如果您没有使用它编制0para,则会得到与您的代码完全相同的结果。

使用此示例数据:

perp

我为items = 100 rpbins, pibins = np.linspace(0, 1, 3), np.linspace(0, 1, 3) x = np.random.rand(items) y = np.random.rand(items) z = np.random.rand(items) 和您的hist

提供此功能
out

>>> hist array([[ 1795., 651.], [ 1632., 740.]]) >>> out array([[ 3690., 1302.], [ 3264., 1480.]]) 除了out[i, j] = 2 * hist[i, j],其中i = j = 0因为每个项目距离out[0, 0] = 2 * hist[0, 0] + items距离。


编辑在tcaswell的评论之后尝试了以下内容:

0

似乎大部分时间花在实例化新数组上,而不是进行实际计算,所以虽然有一些效率可以去掉,但确实没有多少。