如果我有一个数组:
a = np.array([[1,2,3]])
我可以根据数组中的值为这个数组添加一个值。
a = np.insert(a,3,(0.299+a[0][1]*0.587+a[0][2]*0.114))
这会给我以下数组。
array([1, 2, 3, 1.815])
到目前为止一切顺利。但现在我想为具有以下形状的数组执行此操作。
a = np.array(
[
[[1,2,3],[3,4,5]],
[[6,7,8],[9,10,11]]
])
array([[[ 1, 2, 3],
[ 3, 4, 5]],
[[ 6, 7, 8],
[ 9, 10, 11]]])
如果不使用for循环,有没有办法做到这一点?
编辑原始问题有一个最小的工作示例'这太简化了,导致使用了np.sum()函数。现在它遵循以下公式,我需要(0.299 * R + 0.587 * G + 0.114 * B)
答案 0 :(得分:2)
您没有指定所需的输出,但我认为这是您想要的:
a = np.insert(a, 3, a.sum(axis=-1), axis=-1)
a
#[[[ 1 2 3 6]
# [ 3 4 5 12]]
#
# [[ 6 7 8 21]
# [ 9 10 11 30]]]
答案 1 :(得分:1)
没有for循环......你必须在项目上进行迭代,所以你恐怕无法避免。或至少复制行为。
以下内容有望让您更接近实际应用:
#Define a function to apply to the matrix
def f(x, ar):
return np.append(next(ar),x[0]*0.299+x[1]*0.587+x[2]*0.114)
#Create an iterator for semi-efficient stepping through the matrix elements
b = iter(a.reshape((a.shape[0]*a.shape[1],-1)))
#create output array; syntax:
#np.apply_along_axis(1D-function,axis_to_apply_along,object_to_apply_to,optional_arguments)
vals = np.apply_along_axis(f,2,a,b)
#vals
#Out[440]:
#array([[[ 1. , 2. , 3. , 1.815],
# [ 3. , 4. , 5. , 3.815]],
#
# [[ 6. , 7. , 8. , 6.815],
# [ 9. , 10. , 11. , 9.815]]])
但是,for循环在to-loop-over序列上调用iter()
,并对结果使用next()
调用。因此,上述功能基本上以替代方式实现for循环。我们现在唯一希望改变的是,我们避免循环错误的东西,因此最终节省了一些时间..
答案 2 :(得分:1)
您可以尝试:
a = np.array([[[1,2,3],[3,4,5]],[[6,7,8],[9,10,11]]]).astype(np.float_)
a = np.concatenate((a, 0.299*a[:,:,0:1] + 0.587 * a[:,:,1:2] + 0.114*a[:,:,2:3]), axis = 2 )
这给了我:
array([[[ 1. , 2. , 3. , 1.815],
[ 3. , 4. , 5. , 3.815]],
[[ 6. , 7. , 8. , 6.815],
[ 9. , 10. , 11. , 9.815]]])
NB:如果您需要单精度,请使用np.float32
代替np.float_
,这实际上对应于双精度(reference for numpy types here)。当然,如果a
已经有正确的类型,则无需转换。