【问题标题】:How to insert multiple elements in numpy array using np.concatenate()?如何使用 np.concatenate() 在 numpy 数组中插入多个元素?
【发布时间】:2017-07-17 05:37:46
【问题描述】:

Here 已经是在numpy 数组中插入一个元素的答案,其中np.concatenate() 优于np.insert()np.concatenate()np.insert() 花费的时间更少)。但我无法使用它在多个位置插入元素。这是一个例子--

cell = np.array([1, 4, 4, 5, 5, 2, 5, 1, 1, 5])
place = np.argwhere(cell == np.amax(cell)).flatten().tolist()
cell = np.insert(cell, place, 0)

我如何使用 np.concatenate() 来做同样的事情?

【问题讨论】:

  • 对于该示例,place 为空。该命令应该对place 执行什么操作?
  • @Divakar 我的错。现在我已经更正了。
  • 查看np.insert 的代码(例如文档中的源代码)。它根据插入点的数量使用不同的策略。虽然可能性很多,但基本原则很简单。

标签: python arrays numpy


【解决方案1】:
In [178]: cell = np.array([1, 4, 4, 5, 5, 2, 5, 1, 1, 5])
In [179]: place = np.argwhere(cell == np.amax(cell)).flatten().tolist()
In [180]: place
Out[180]: [3, 4, 6, 9]
In [181]: np.insert(cell, place, 0)
Out[181]: array([1, 4, 4, 0, 5, 0, 5, 2, 0, 5, 1, 1, 0, 5])
In [182]: np.concatenate([cell[:3],[0],cell[3:4],[0],cell[4:6],[0],cell[6:9],[0] ,cell[9:]])
Out[182]: array([1, 4, 4, 0, 5, 0, 5, 2, 0, 5, 1, 1, 0, 5])

可以通过对place 值的某种列表迭代来概括构造连接列表。细节留给读者。

insert,有多个插入,使用mask 方法,我们可以对其进行逆向工程:

它在哪里插入了 0?

In [193]: res = np.insert(cell, place, 0)
In [194]: np.where(res==0)
Out[194]: (array([ 3,  5,  8, 12], dtype=int32),)

这与将0,1,2,3添加到位置相同:

In [195]: np.arange(n)+place
Out[195]: array([ 3,  5,  8, 12])

制作一个目标数组和掩码数组:

In [196]: out = np.zeros(len(cell)+n, dtype=cell.dtype)
In [197]: mask = np.ones(len(out), dtype=bool)

使用掩码来定义我们插入原始值的位置

In [198]: mask[Out[195]]=False
In [199]: out[mask] = cell
In [200]: out
Out[200]: array([1, 4, 4, 0, 5, 0, 5, 2, 0, 5, 1, 1, 0, 5])

由于插入值为0,我们不需要再做任何事情了。

我在上一个答案中建议concatenate 比插入更快,因为insert 更通用并且需要更多时间来设置。情况可能也是如此。但我预计时间不会有一点改善。


广义连接

In [235]: catlist = [cell[:place[0]],[0]]
In [236]: for i in range(n-1):
     ...:     catlist.append(cell[place[i]:place[i+1]])
     ...:     catlist.append([0])
     ...:     
In [237]: catlist.append(cell[place[-1]:])
In [238]: np.concatenate(catlist)
Out[238]: array([1, 4, 4, 0, 5, 0, 5, 2, 0, 5, 1, 1, 0, 5])

【讨论】:

  • 谢谢。这是一个不错的方法,但问题是我必须处理 10^18 个元素,这就是我尝试实现 concatenate() 的原因,否则我可以接受 insert() .如果您有任何比insert() 花费更少时间的更好的解决方案,那对我来说将非常有帮助。我已经尝试concatenate()for 循环,但是一个一个插入一个元素需要将近~500 秒(对于10 ^ 9 个元素)。再次感谢您。
  • 如果cellplace 大,我预计concatenate 方法(请参阅我的上次编辑)会更快,因为它适用于cell 的大片。但是,如果切片又小又多,那么 insert 所做的蒙版复制可能会更快。
  • 我已经完全尝试了您在上次编辑中所说的内容。正如你所说,这里的地方不小。所以insert 会帮助我。谢谢。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-08-12
  • 1970-01-01
  • 1970-01-01
  • 2017-06-07
  • 1970-01-01
  • 2019-04-24
相关资源
最近更新 更多