【问题标题】:how to efficiently select multiple slices from an array?如何有效地从数组中选择多个切片?
【发布时间】:2013-03-20 15:22:09
【问题描述】:

给定一个数组

d = np.random.randn(100)

还有一个索引数组

i = np.random.random_integers(low=3, high=d.size - 5, size=20)

我怎样才能有效地创建一个二维数组r

r.shape = (20, 8)

这样对于所有j=0..19

r[j] = d[i[j]-3:i[j]+5]

在我的例子中,数组非常大(~200000 而不是 100 和 20),所以一些快速的东西会很有用。

【问题讨论】:

  • lowhigh 有什么不同吗?喜欢low=0, high=d.size - 8d[i[j]:i[j]+8]
  • 是的,它确实有所作为。如果i 的元素是<3,那么i[j]-3 是负数。上限类似。
  • 但是如果all(0<=elem<=92 for elem in i) is True 那么d[i[j]:i[j]+8] 会是一样的,对吧?

标签: python numpy indexing


【解决方案1】:

您可以创建数据的窗口视图,即(93, 8) 数组,其中[i, j] 项是原始数组的[i+j] 项,如下所示:

>>> from numpy.lib.stride_tricks import as_strided
>>> wd = as_strided(d, shape=(len(d)-8+1, 8), strides=d.strides*2)

您现在可以将所需的切片提取为:

>>> r = wd[i-3]

请注意,wd 只是原始数据的视图,因此它不需要额外的内存。使用任意索引提取 r 的那一刻,数据将被复制。因此,根据您想如何使用 r 数组,您可能希望尽可能地延迟它,或者甚至完全避免它:您始终可以访问行 r[j]wd[j-3] 而不会触发复制。

【讨论】:

  • 这里不要使用take,除非你先重写函数。很高兴知道 take 通常更快,但至少在这里通常是一个非常糟糕的主意(当然也不是更快)。
  • @seberg 我猜这是复制,无论如何都必须发生,这使它成为一个坏主意,对吧?将编辑我的答案:谢谢!
  • 好吧,我相信正常的切片不会做临时副本......所以如果你只拿几个项目,你可能会膨胀大量内存......
猜你喜欢
  • 2017-12-22
  • 2017-09-10
  • 2019-04-02
  • 1970-01-01
  • 2018-11-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多