我试图找到一种方法来矢量化一个操作,我采用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])
这次通过向每个点添加+ = .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])
答案 0 :(得分: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])
答案 1 :(得分: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回答一个-liner:
>>> (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)
答案 2 :(得分:1)
对于第一个示例,您可以执行输入和模板的外部产品并重新整形结果:
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])
请参阅:
答案 3 :(得分:1)
您似乎希望在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])