繁体   English   中英

向量化numpy数组扩展

[英]Vectorize numpy array expansion

我试图找到一种向量化操作的方法,其中我采用1个numpy数组并将每个元素扩展为4个新点。 我目前正在使用Python循环进行此操作。 首先让我解释一下算法。

input_array = numpy.array([1, 2, 3, 4])

我想将该数组中的每个元素“扩展”或“扩展”到4点。 因此,元素零(值1)将扩展为以下4点:

[0, 1, 1, 0]

对于每个元素,最终的最终数组都是这样:

[0, 1, 1, 0, 0, 2, 2, 0, 0, 3, 3, 0, 0, 4, 4, 0]

我想使代码稍微通用一些,以便我也可以以其他方式执行此“扩展”。 例如:

input_array = numpy.array([1, 2, 3, 4])

这次,通过在每个点上添加+ = 0.2来扩展每个点。 因此,最终的数组将是:

[.8, .8, 1.2, 1.2, 1.8, 1.8, 2.2, 2.2, 2.8, 2.8, 3.2, 3.2, 3.8, 3.8, 4.2, 4.2]

我当前正在使用的代码如下所示。 这是一种非常幼稚的方法,但是似乎有一种方法可以加快大型阵列的运行速度:

output = []
for x in input_array:
    output.append(expandPoint(x))

output = numpy.concatenate(output)

def expandPoint(x):
    return numpy.array([0, x, x, 0])

def expandPointAlternativeStyle(x):
    return numpy.array([x - .2, x - .2, x + .2, x + .2])

对于第一个示例,可以使用np.kron

>>> a = np.array([0, 1, 1, 0])
>>> np.kron(input_array, a)
array([0, 1, 1, 0, 0, 2, 2, 0, 0, 3, 3, 0, 0, 4, 4, 0])

对于第二个示例,可以使用np.repeatnp.tile

>>> b = np.array([-0.2, -0.2, 0.2, 0.2])
>>> np.repeat(input_array, b.size) + np.tile(b, input_array.size)
array([ 0.8,  0.8,  1.2,  1.2,  1.8,  1.8,  2.2,  2.2,  2.8,  2.8,  3.2,
        3.2,  3.8,  3.8,  4.2,  4.2])

我不确定算法的逻辑,但是我认为如果希望每个点都围绕它extend ,然后将它们全部排队,则最好的方法是增大尺寸,然后采用扁平化的版本。 对于第一个示例:

>>> x = np.array([1,2,3,4])
>>> x
array([1, 2, 3, 4])
>>> y = np.empty((len(x), 4))
>>> y[:, [0, 3]] = 0
>>> y[:, 1:3] = x[:, None]
>>> y
array([[ 0.,  1.,  1.,  0.],
       [ 0.,  2.,  2.,  0.],
       [ 0.,  3.,  3.,  0.],
       [ 0.,  4.,  4.,  0.]])
>>> y.reshape((4*len(x),))  # Flatten it back
array([ 0.,  1.,  1.,  0.,  0.,  2.,  2.,  0.,  0.,  3.,  3.,  0.,  0.,
    4.,  4.,  0.])

然后如何制作该泛型取决于您的算法,我不确定要完全遵循该算法。但这应该为您提供一些入门指南。

编辑 :正如其他人所说,实际上您可以以更简洁的方式对外部产品进行所有操作,这可能与您的算法更紧密地匹配,例如,羞耻地使YXD回答单一问题:

>>> (x[:, None] * np.array([0,1,1,0])[None, :]).flatten()
array([0, 1, 1, 0, 0, 2, 2, 0, 0, 3, 3, 0, 0, 4, 4, 0])

但是,原理是在将其扩展到原始尺寸(1)之前,它仍应沿较高的尺寸(2)前进。

对于第一个示例,您可以对输入和模板进行外积运算并调整结果的形状:

input_array = np.array([1, 2, 3, 4])
template = np.array([0, 1, 1, 0])

np.multiply.outer(input_array, template)
# array([[0, 1, 1, 0],
#        [0, 2, 2, 0],
#        [0, 3, 3, 0],
#        [0, 4, 4, 0]])

result = np.multiply.outer(input_array, template).ravel()
# array([0, 1, 1, 0, 0, 2, 2, 0, 0, 3, 3, 0, 0, 4, 4, 0])

同样,对于第二个示例,您可以使用np.add.outer

np.add.outer(input_array, [-0.2, -0.2, 0.2, 0.2]).ravel()
# array([ 0.8,  0.8,  1.2,  1.2,  1.8,  1.8,  2.2,  2.2,  2.8,  2.8,  3.2,
        3.2,  3.8,  3.8,  4.2,  4.2])

看到:

似乎您想在input_array和包含扩展元素的数组之间进行input_array元素的操作。 对于这些,您可以使用broadcasting

对于第一个示例,似乎您正在执行elementwise multiplication -

In [424]: input_array = np.array([1, 2, 3, 4])
     ...: extend_array = np.array([0, 1, 1, 0])
     ...: 

In [425]: (input_array[:,None] * extend_array).ravel()
Out[425]: array([0, 1, 1, 0, 0, 2, 2, 0, 0, 3, 3, 0, 0, 4, 4, 0])

对于第二个示例,似乎您正在执行elementwise addition -

In [422]: input_array = np.array([1, 2, 3, 4])
     ...: extend_array = np.array([-0.2, -0.2, 0.2, 0.2])
     ...: 

In [423]: (input_array[:,None] + extend_array).ravel()
Out[423]: 
array([ 0.8,  0.8,  1.2,  1.2,  1.8,  1.8,  2.2,  2.2,  2.8,  2.8,  3.2,
        3.2,  3.8,  3.8,  4.2,  4.2])

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM