2013-03-20 86 views
2

鉴于阵列如何有效地从数组中选择多个切片?

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),所以快速的东西会很有用。

+0

“低”和“高”有什么区别吗?像'low = 0,high = d.size - 8'和'd [i [j]:i [j] +8]'? – Kabie 2013-03-20 16:04:49

+0

是的,它确实有所作为。如果'i'的元素是'<3',那么'i [j] -3'是负数。类似的上限。 – 2013-03-20 16:13:49

+0

但是如果'all(0 <= elem <= 92 for elem in i)is True'那么'd [i [j]:i [j] +8]'是一样的,对吗? – Kabie 2013-03-20 16:21:16

回答

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]而不触发副本。

+1

除非您首先重写函数,否则请勿使用此处。很高兴知道这个比赛的速度更快,但这至少是一个非常糟糕的主意(当然不会更快)。 – seberg 2013-03-20 16:19:36

+0

@seberg我猜这是复制,无论发生什么都必须发生,这使得它不好主意,对吧?将编辑我的答案:谢谢! – Jaime 2013-03-20 16:28:03

+0

那么,正常的切片将不会做临时副本,我相信...所以如果你只有几个项目,你可能会膨胀记忆大时间... – seberg 2013-03-20 16:37:59