gpt4 book ai didi

Python - 向量化滑动窗口

转载 作者:太空狗 更新时间:2023-10-29 22:05:45 25 4
gpt4 key购买 nike

我正在尝试矢量化滑动窗口操作。对于 1-d 情况,一个有用的示例可以按照以下行进行:

x= vstack((np.array([range(10)]),np.array([range(10)])))

x[1,:]=np.where((x[0,:]<5)&(x[0,:]>0),x[1,x[0,:]+1],x[1,:])

索引 <5 的每个当前值的 n+1 值。但是我得到这个错误:

x[1,:]=np.where((x[0,:]<2)&(x[0,:]>0),x[1,x[0,:]+1],x[1,:])
IndexError: index (10) out of range (0<=index<9) in dimension 1

奇怪的是,对于 n-1 值我不会得到这个错误,这意味着索引小于 0。它似乎并不介意:

x[1,:]=np.where((x[0,:]<5)&(x[0,:]>0),x[1,x[0,:]-1],x[1,:])

print(x)

[[0 1 2 3 4 5 6 7 8 9]
[0 0 1 2 3 5 6 7 8 9]]

这附近有什么吗?我的方法完全错误吗?如有任何意见,我们将不胜感激。

编辑:

这就是我想要实现的,我将一个矩阵展平为一个 numpy 数组,我想在该数组上计算每个单元格的 6x6 邻域的平均值:

matriz = np.array([[1,2,3,4,5],
[6,5,4,3,2],
[1,1,2,2,3],
[3,3,2,2,1],
[3,2,1,3,2],
[1,2,3,1,2]])

# matrix to vector
vector2 = ndarray.flatten(matriz)

ncols = int(shape(matriz)[1])
nrows = int(shape(matriz)[0])

vector = np.zeros(nrows*ncols,dtype='float64')


# Interior pixels
if ( (i % ncols) != 0 and (i+1) % ncols != 0 and i>ncols and i<ncols*(nrows-1)):

vector[i] = np.mean(np.array([vector2[i-ncols-1],vector2[i-ncols],vector2[i-ncols+1],vector2[i-1],vector2[i+1],vector2[i+ncols-1],vector2[i+ncols],vector2[i+ncols+1]]))

最佳答案

如果我对这个问题的理解正确,你想对索引取所有数字的平均值 1 步,忽略索引。

我已经修补了你的功能,我相信你想要这样的东西:

def original(matriz):

vector2 = np.ndarray.flatten(matriz)

nrows, ncols= matriz.shape
vector = np.zeros(nrows*ncols,dtype='float64')

# Interior pixels
for i in range(vector.shape[0]):
if ( (i % ncols) != 0 and (i+1) % ncols != 0 and i>ncols and i<ncols*(nrows-1)):

vector[i] = np.mean(np.array([vector2[i-ncols-1],vector2[i-ncols],\
vector2[i-ncols+1],vector2[i-1],vector2[i+1],\
vector2[i+ncols-1],vector2[i+ncols],vector2[i+ncols+1]]))

我使用切片和 View 重写了这个:

def mean_around(arr):
arr=arr.astype(np.float64)

out= np.copy(arr[:-2,:-2]) #Top left corner
out+= arr[:-2,2:] #Top right corner
out+= arr[:-2,1:-1] #Top center
out+= arr[2:,:-2] #etc
out+= arr[2:,2:]
out+= arr[2:,1:-1]
out+= arr[1:-1,2:]
out+= arr[1:-1,:-2]

out/=8.0 #Divide by # of elements to obtain mean

cout=np.empty_like(arr) #Create output array
cout[1:-1,1:-1]=out #Fill with out values
cout[0,:]=0;cout[-1,:]=0;cout[:,0]=0;cout[:,-1]=0 #Set edges equal to zero

return cout

使用 np.empty_like 然后填充边缘似乎比 np.zeros_like 稍微快一些。首先让我们仔细检查它们使用您的 matriz 数组给出相同的东西。

print np.allclose(mean_around(matriz),original(matriz))
True

print mean_around(matriz)
[[ 0. 0. 0. 0. 0. ]
[ 0. 2.5 2.75 3.125 0. ]
[ 0. 3.25 2.75 2.375 0. ]
[ 0. 1.875 2. 2. 0. ]
[ 0. 2.25 2.25 1.75 0. ]
[ 0. 0. 0. 0. 0. ]]

一些时间:

a=np.random.rand(500,500)

print np.allclose(original(a),mean_around(a))
True

%timeit mean_around(a)
100 loops, best of 3: 4.4 ms per loop

%timeit original(a)
1 loops, best of 3: 6.6 s per loop

大约 1500 倍加速。

看起来是使用 numba 的好地方:

def mean_numba(arr):
out=np.zeros_like(arr)
col,rows=arr.shape

for x in xrange(1,col-1):
for y in xrange(1,rows-1):
out[x,y]=(arr[x-1,y+1]+arr[x-1,y]+arr[x-1,y-1]+arr[x,y+1]+\
arr[x,y-1]+arr[x+1,y+1]+arr[x+1,y]+arr[x+1,y-1])/8.
return out

nmean= autojit(mean_numba)

现在让我们与所有提出的方法进行比较。

a=np.random.rand(5000,5000)

%timeit mean_around(a)
1 loops, best of 3: 729 ms per loop

%timeit nmean(a)
10 loops, best of 3: 169 ms per loop

#CT Zhu's answer
%timeit it_mean(a)
1 loops, best of 3: 36.7 s per loop

#Ali_m's answer
%timeit fast_local_mean(a,(3,3))
1 loops, best of 3: 4.7 s per loop

#lmjohns3's answer
%timeit scipy_conv(a)
1 loops, best of 3: 3.72 s per loop

numba up 的 4 倍速度是非常名义上的,表明 numpy 代码已经达到了它的预期效果。我提取了所提供的其他代码,尽管我确实必须更改@CTZhu 的答案以包含不同的数组大小。

关于Python - 向量化滑动窗口,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18424900/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com