向量化数组操作,依次排除数组元素

时间:2019-01-09 09:56:07

标签: python arrays numpy vectorization

我正在为某种矢量操作寻找Python中最有效的方法,

  • 对于每个数组元素,获取一个由乘积与所有其他数组元素的乘积之和组成的数组。

例如,假设我们有两个形状相同的数组

a = [ 1, 2, 3, 4]
b = [ 1, 0, -1, 2]

我想做的是构造一个具有相同形状的新数组c,这样

c[i] = ( sum of a[j]*b[j] while j!=i )

先发制人

c = [ 5, 6, 9, -2]

如果我们使用多个for循环,这并不是一个棘手的问题,但是对于非常大的数组,它可能会很慢。我听说使用遮罩数组np.ma可以提供一些帮助,但是似乎该方法仍然需要对每个元素进行迭代遮罩。

我想知道是否有比这些方法更快的方法,尤其是利用矢量化手术形式。

2 个答案:

答案 0 :(得分:1)

当然使用NumPy

In [3]: import numpy as np

In [4]: a = np.array([1, 2, 3, 4])

In [5]: b = np.array([1, 0, -1, 2])

In [6]: c = a * b

In [7]: c = c.sum() - c

In [8]: c
Out[8]: array([ 5,  6,  9, -2])

答案 1 :(得分:0)

不确定是否有一种方法可以用简单的numpy进行(如果有的话)。但是,只要您要处理迭代,您的方法就是求和迭代器和列表理解。

nsize = 500
a = np.random.randint(-3, 8, nsize)
b = np.random.randint(-3, 8, nsize)

首先想到的是普通的for循环。解决方案如下:

c = list()
for i in range(nsize):
    sum_entry = 0
    for j in range(nsize):
        if not j == i:
            sum_entry += a[j] * b[j]
    c.append(sum_entry)

对于nsize = 500,这花费了0.098秒。

一种更快,更Python化的方式是将sum-iterator和列表理解结合起来:

c = [sum(a[j]*b[j] for j in range(nsize) if not j == i) for i in range(nsize)]

nsize = 500花了我0.075秒,因此快了30%。