我有一个numpy数组,我想获得第i点的"邻域".通常我使用的数组是二维的,但下面的一维示例说明了我正在寻找的内容.如果
A = numpy.array([0,10,20,30,40,50,60,70,80,90])
Run Code Online (Sandbox Code Playgroud)
然后,元素4的(大小5)邻域是[20,30,40,50,60]
,并且这可以通过这样做容易地获得A[i-2:i+3]
.
但是,我还需要邻域"环绕"数组的边缘,以便元素0 [80,90,0,10,20]
的邻域是和元素9的邻域[70,80,90,0,10]
.我似乎无法找到一种优雅的方法来做到这一点,所以每次出现时我都不得不使用一些复杂,烦人的逻辑(这对我来说很常见).在2D情况下,点的邻域将是矩形阵列.
所以我的问题是,是否有一种巧妙的方式来表达这个"环绕邻居"操作在numpy?我更喜欢返回切片而不是副本的东西,但可读性和速度是最重要的考虑因素.
Hen*_*rik 27
numpy.take
在'wrap'
模式下将使用您的索引模数组的长度.
indices = range(i-2,i+3)
neighbourhood = A.take(indices, mode='wrap')
Run Code Online (Sandbox Code Playgroud)
请参阅文档了解详细信 numpy.take
您可以使用参数axis=0
的numpy.take
为第二阵列.
A = zip(range(0,101,10),range(0,11)) #create 2-d list
A = numpy.array(A) #create 2-d array
indices = range(i-2,i+3)
neightbourhood = A.take(indices,axis=0,mode='wrap')
Run Code Online (Sandbox Code Playgroud)
同样axis=0
适用于n*m尺寸......
注意:对于邻居不需要包装的情况,numpy.take
比简单地切片要慢A[i-2:i+3]
。你可能想用一些条件语句来包装你的邻居函数:
def neighbors(a,i,n):
N = a.shape[0]
if i - n < 0 and i + n > 0:
indices = range(i-n,i+n+1)
nbrs = a.take(indices, mode='wrap')
elif i-n < N - 1 and i+n > N - 1:
indices = range(i-n,i+n+1)
nbrs = a.take(indices, mode='wrap')
else:
nbrs = a[i-n:i+n+1]
return nbrs
Run Code Online (Sandbox Code Playgroud)
如果您发现自己在遍历数组时使用邻居,例如在居中移动平均线中,您会发现这需要更少的时间,尤其是对于较长的数组:
这是我使用的移动平均函数:
def moving_average(a,n=1):
N = a.shape[0]
ma = np.empty(N)
for i in range(N):
if n*2+1 > N:
ma[i] = a.mean()
else:
ma[i] = neighbors(a,i,n).mean()
return ma
Run Code Online (Sandbox Code Playgroud)
我相信这些功能可以进一步改进。我愿意接受建议。
归档时间: |
|
查看次数: |
9087 次 |
最近记录: |