将元素插入numpy数组的更好方法

时间:2018-09-15 15:42:24

标签: python arrays python-2.7 numpy scipy

我有一个numpy数组,并且有一个要在该数组的特定位置(不连续)插入的元素列表。索引位于另一个numpy数组中。

target answer: [1,2,3,4,5]
original array: [1,3,5]
elements to insert: [2,4]
indices: [1,3]

numpy.insert(arr,[1,3],[2,4])未能获得理想的结果。它给出[1,2,3,5,4]。 有指针吗?

2 个答案:

答案 0 :(得分:3)

np.insert使用范围偏移索引-

np.insert(a, add_idx - np.arange(len(add_idx)), add_val)

样品运行-

In [20]: a
Out[20]: array([1, 3, 5])

In [21]: add_idx
Out[21]: [1, 3]

In [22]: add_val
Out[22]: [2, 4]

In [23]: np.insert(a, add_idx - np.arange(len(add_idx)), add_val)
Out[23]: array([1, 2, 3, 4, 5])

答案 1 :(得分:0)

列表方法是:

In [122]: alist=[1,3,5]
In [123]: for i,j in zip([1,3],[2,4]):
     ...:     alist[i:i] = [j]
     ...:     
In [124]: alist
Out[124]: [1, 2, 3, 4, 5]

np.insert是一个复杂的函数,根据输入的索引采用不同的方法。但是在这种情况下,使用布尔掩码方法:

In [126]: arr = np.array([1,3,5])
In [127]: res = np.zeros(5, int) # 5 is len(arr)+len([2,4])
In [128]: mask = res.astype(bool)
In [129]: mask[[1,3]] = True
In [130]: mask
Out[130]: array([False,  True, False,  True, False])
In [131]: res[mask] = [2,4]
In [132]: res[~mask] = arr
In [133]: res
Out[133]: array([1, 2, 3, 4, 5])

mask定义了新值应该去的地方,而~mask则定义了原始值去的地方。

insert假定索引是相对于源数组而不是目标数组给出的。要执行相同的操作,必须给它[1,2],换句话说,在arr[1]arr[2]之后。 insert会将[1,2]调整为[1,3]以使用上述屏蔽方法。 @Divakar的答案将您的[1,3]转换为[1,2]期望的insert。实际上,他正在补偿insert通常会增加的偏移量。


如果我们使用[1,2](相对于源列表的索引),那么我上面使用的列表迭代是错误的。它不能说明列表在插入2之后增长的事实:

In [134]: alist=[1,3,5]
In [135]: for i,j in zip([1,2],[2,4]):
     ...:     alist[i:i] = [j]   
In [136]: alist
Out[136]: [1, 2, 4, 3, 5]

为了弥补这一点,一个常见的技巧是按相反的顺序插入

In [137]: alist=[1,3,5]
In [138]: for i,j in zip([1,2][::-1],[2,4][::-1]):
     ...:     alist[i:i] = [j]
In [139]: alist
Out[139]: [1, 2, 3, 4, 5]