[英]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.repeat
和np.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.