概括数组元素“邻居堆叠成三维阵列 [英] Generalize stacking of array elements' neighbors into 3-D array
问题描述
给出一个二维数组,我想创建一个三维数组,其中沿第三维的值(即堆叠[行,列,:]
)是在扁平原始数组的邻居[行,列]
。我想概括这一过程处理任意(但是合理的)搜索半径。
Given a 2D array, I would like to create a 3D array where the values along the third dimension at (i.e. stacked[row, col, :]
) are the flattened neighbors of the original array at [row, col]
. I would like to generalize this process to handle an arbitrary (but reasonable) search radius.
这问题似乎前途,但我不知道我能真的利用其无(夫妇)为循环方法。我目前的做法,为1的搜索半径应用,为简洁起见说明与下面的例子。
This question seemed promising, but I'm not sure I can really utilize its approach without a (couple of) for
loops. My current approach, applied with a search radius of 1, for brevity's sake is illustrated with the example below.
另外这款<一个href=\"http://stackoverflow.com/questions/4936620/using-strides-for-an-efficient-moving-average-filter\">question +答案接近,但我专门找了纯粹采用了智能索引,以避免环路的解决方案。
Also this question + answer were close, but I'm specifically looking for a solution that purely uses smart indexing to avoid loops.
import numpy as np
np.random.seed(0)
x = np.random.random_integers(0, 10, size=(4, 5))
print(x) # * highlights the neighbors we'll see later
[[ 5 0 3 3 7]
[ 9 *3 *5 *2 4]
[ 7 *6 *8 *8 10]
[ 1 *6 *7 *7 8]]
# padding the edges
padded = np.pad(x, mode='edge', pad_width=1) # pad_width -> search radius
print(padded)
[[ 5 5 0 3 3 7 7]
[ 5 5 0 3 3 7 7]
[ 9 9 3 5 2 4 4]
[ 7 7 6 8 8 10 10]
[ 1 1 6 7 7 8 8]
[ 1 1 6 7 7 8 8]]
于是,我们可以堆叠了所有的邻居。 这是我想的运行概括
blocked = np.dstack([
padded[0:-2, 0:-2], # upper left
padded[0:-2, 1:-1], # upper center
padded[0:-2, 2:], # upper right
padded[1:-1, 0:-2], # middle left...
padded[1:-1, 1:-1],
padded[1:-1, 2:],
padded[2:, 0:-2], # lower left ...
padded[2:, 1:-1],
padded[2:, 2:],
])
和访问邻居如果单元格看起来像这样(调用重塑
仅供说明)
And accessing the neighbors if a cell looks like this (the call to reshape
for illustrative purposes only)
print(blocked[2, 2, :].reshape(3, 3))
[[3 5 2]
[6 8 8]
[6 7 7]]
主要问题
对于给定的搜索半径,有没有一概而论调用 np.dstack
?
推荐答案
这可能是一种方法 -
This could be one approach -
import numpy as np
# Parameters
R = 3 # Radius
M1,N1 = padded.shape
rowlen = N1 - R + 1
collen = M1 - R + 1
# Linear indices for the starting R x R block
idx1 = np.arange(R)[:,None]*N1 + np.arange(R)
# Offset (from the starting block indices) linear indices for all the blocks
idx2 = np.arange(collen)[:,None]*N1 + np.arange(rowlen)
# Finally, get the linear indices for all blocks
all_idx = idx1.ravel()[None,None,:] + idx2[:,:,None]
# Index into padded for the final output
out = padded.ravel()[all_idx]
下面是半径的样本来看, R = 4
-
In [259]: padded
Out[259]:
array([[ 5, 5, 0, 3, 3, 3],
[ 5, 5, 0, 3, 3, 3],
[ 7, 7, 9, 3, 5, 5],
[ 2, 2, 4, 7, 6, 6],
[ 8, 8, 8, 10, 1, 1],
[ 6, 6, 7, 7, 8, 8],
[ 6, 6, 7, 7, 8, 8]])
In [260]: out
Out[260]:
array([[[ 5, 5, 0, 3, 5, 5, 0, 3, 7, 7, 9, 3, 2, 2, 4, 7],
[ 5, 0, 3, 3, 5, 0, 3, 3, 7, 9, 3, 5, 2, 4, 7, 6],
[ 0, 3, 3, 3, 0, 3, 3, 3, 9, 3, 5, 5, 4, 7, 6, 6]],
[[ 5, 5, 0, 3, 7, 7, 9, 3, 2, 2, 4, 7, 8, 8, 8, 10],
[ 5, 0, 3, 3, 7, 9, 3, 5, 2, 4, 7, 6, 8, 8, 10, 1],
[ 0, 3, 3, 3, 9, 3, 5, 5, 4, 7, 6, 6, 8, 10, 1, 1]],
[[ 7, 7, 9, 3, 2, 2, 4, 7, 8, 8, 8, 10, 6, 6, 7, 7],
[ 7, 9, 3, 5, 2, 4, 7, 6, 8, 8, 10, 1, 6, 7, 7, 8],
[ 9, 3, 5, 5, 4, 7, 6, 6, 8, 10, 1, 1, 7, 7, 8, 8]],
[[ 2, 2, 4, 7, 8, 8, 8, 10, 6, 6, 7, 7, 6, 6, 7, 7],
[ 2, 4, 7, 6, 8, 8, 10, 1, 6, 7, 7, 8, 6, 7, 7, 8],
[ 4, 7, 6, 6, 8, 10, 1, 1, 7, 7, 8, 8, 7, 7, 8, 8]]])
这篇关于概括数组元素“邻居堆叠成三维阵列的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!