在2D阵列中插入元素的有效方法

时间:2013-11-28 17:38:57

标签: python arrays numpy

我无法将此功能转换为矢量化功能:

a=np.asarray([[1,2,3],[3,4,5]])
inds=np.asarray([0,2])
vals=np.asarray([10,12])
def new_insert(arr,inds,vals):
    ret=np.zeros((arr.shape[0],arr.shape[1]+1))
    for i in range(arr.shape[0]):
        ret[i]=np.insert(arr[i],inds[i],vals[i])
    return ret
print new_insert(a,inds,vals)

输出:

[[ 10.   1.   2.   3.]
 [  3.   4.  12.   5.]]

有帮助吗?

2 个答案:

答案 0 :(得分:2)

您可以切换到数组a的1d视图:

shape = a.shape
a.shape = np.multiply(*shape)

重新计算一维数组的索引:

ind1d = [i+e*shape[0] for i, e in enumerate(ind)]

插入1d数组

b = np.insert(a, ind1d, vals)

并将结果重新塑造为2d

b.shape = (shape[0], shape[1]+1)

所以,最后,我们得到了

>>> b
array([[10,  1,  2,  3],
       [ 3,  4, 12,  5]])

@askewchan在评论中提出的在线人,使用np.ravel_multi_index帮助函数来压缩索引:

>>> np.insert(a.flat, np.ravel_multi_index((np.arange(ind.size), ind), 
...               a.shape), vals).reshape(a.shape[0], -1)
array([[10,  1,  2,  3],
       [ 3,  4, 12,  5]])

答案 1 :(得分:1)

想我会将我的评论发布到@ alko的答案作为答案,因为它看起来有点令人困惑:

b = np.insert(a.flat, np.ravel_multi_index((np.arange(ind.size), ind), a.shape), vals).reshape(a.shape[0], -1)

这与@ alko基本相同,但它有一些优点:

  • 使用a迭代器而不是实际更改a.flat的形状,修改a本身。
  • 使用np.ravel_multi_index创建ind1d数组而不是手动执行此操作,以避免潜在的错误。
  • 它快一点点(10%)。

在类似于alko的步骤中,这就是它的作用:

ind1d = np.ravel_multi_index((np.arange(ind.size), ind), a.shape)

其中ind引用列索引,因此使用np.arange来引用行索引。然后,插入a.flat迭代器而不是重新整形的a

b = np.insert(a.flat, ind1d, vals)

最后,重塑:

b = b.reshape(a.shape[0], -1) # the -1 allows any shape at the end