Python 矩阵:按n个位置高效移动第n行
我有一个numpy 2d数组,我需要以一种方式对它进行变换,第一行保持不变,第二行向右移动一个位置,它可以环绕,也可以将零填充到前面。第三行向右移动3个位置,以此类推。 我可以通过for循环来实现这一点,但这不是很有效。我猜应该有一个过滤矩阵,乘以原始矩阵会有相同的效果,或者可能有一个小技巧,可以帮助我做到这一点?谢谢 我已经研究过numpy.roll,但我不认为它可以在每一行单独工作Python 矩阵:按n个位置高效移动第n行,python,numpy,matrix,matrix-transform,Python,Numpy,Matrix,Matrix Transform,我有一个numpy 2d数组,我需要以一种方式对它进行变换,第一行保持不变,第二行向右移动一个位置,它可以环绕,也可以将零填充到前面。第三行向右移动3个位置,以此类推。 我可以通过for循环来实现这一点,但这不是很有效。我猜应该有一个过滤矩阵,乘以原始矩阵会有相同的效果,或者可能有一个小技巧,可以帮助我做到这一点?谢谢 我已经研究过numpy.roll,但我不认为它可以在每一行单独工作 import numpy as np p = np.array([[1,2,3,4],[5,6,7,8],[9
import numpy as np
p = np.array([[1,2,3,4],[5,6,7,8],[9,10,11,12],[13,14,15,16]])
'''
p = [ 1 2 3 4
5 6 7 8
9 10 11 12
13 14 15 16]
desired output:
p'= [ 1 2 3 4
0 5 6 7
0 0 9 10
0 0 0 13]
'''
我们可以将滑动窗口提取到一个零填充版本的输入中,以获得一种内存有效的方法,从而提高性能。要获得这些窗口,我们可以利用基于 因此,解决办法是-
from skimage.util.shape import view_as_windows
def slide_by_one(p):
m,n = p.shape
z = np.zeros((m,m-1),dtype=p.dtype)
a = np.concatenate((z,p),axis=1)
w = view_as_windows(a,(1,p.shape[1]))[...,0,:]
r = np.arange(m)
return w[r,r[::-1]]
样本运行-
In [60]: p # generic sample of size mxn
Out[60]:
array([[ 1, 5, 9, 13, 17],
[ 2, 6, 10, 14, 18],
[ 3, 7, 11, 15, 19],
[ 4, 8, 12, 16, 20]])
In [61]: slide_by_one(p)
Out[61]:
array([[ 1, 5, 9, 13, 17],
[ 0, 2, 6, 10, 14],
[ 0, 0, 3, 7, 11],
[ 0, 0, 0, 4, 8]])
我们可以利用常规的rampy模式,以更原始的方式使用np.lib.stride\u技巧-
def slide_by_one_v2(p):
m,n = p.shape
z = np.zeros((m,m-1),dtype=p.dtype)
a = np.concatenate((z,p),axis=1)
s0,s1 = a.strides
return np.lib.stride_tricks.as_strided(a[:,m-1:],shape=(m,n),strides=(s0-s1,s1))
另一个有遮罩的-
我们可以将滑动窗口提取到一个零填充版本的输入中,以获得一种内存有效的方法,从而提高性能。要获得这些窗口,我们可以利用基于 因此,解决办法是-
from skimage.util.shape import view_as_windows
def slide_by_one(p):
m,n = p.shape
z = np.zeros((m,m-1),dtype=p.dtype)
a = np.concatenate((z,p),axis=1)
w = view_as_windows(a,(1,p.shape[1]))[...,0,:]
r = np.arange(m)
return w[r,r[::-1]]
样本运行-
In [60]: p # generic sample of size mxn
Out[60]:
array([[ 1, 5, 9, 13, 17],
[ 2, 6, 10, 14, 18],
[ 3, 7, 11, 15, 19],
[ 4, 8, 12, 16, 20]])
In [61]: slide_by_one(p)
Out[61]:
array([[ 1, 5, 9, 13, 17],
[ 0, 2, 6, 10, 14],
[ 0, 0, 3, 7, 11],
[ 0, 0, 0, 4, 8]])
我们可以利用常规的rampy模式,以更原始的方式使用np.lib.stride\u技巧-
def slide_by_one_v2(p):
m,n = p.shape
z = np.zeros((m,m-1),dtype=p.dtype)
a = np.concatenate((z,p),axis=1)
s0,s1 = a.strides
return np.lib.stride_tricks.as_strided(a[:,m-1:],shape=(m,n),strides=(s0-s1,s1))
另一个有遮罩的-
下面是一个基于零填充和重塑的简单方法。它很快,因为它避免了高级索引和其他开销
def pp(p):
m,n = p.shape
aux = np.zeros((m,n+m-1),p.dtype)
np.copyto(aux[:,:n],p)
return aux.ravel()[:-m].reshape(m,n+m-2)[:,:n].copy()
下面是一个基于零填充和重塑的简单方法。它很快,因为它避免了高级索引和其他开销
def pp(p):
m,n = p.shape
aux = np.zeros((m,n+m-1),p.dtype)
np.copyto(aux[:,:n],p)
return aux.ravel()[:-m].reshape(m,n+m-2)[:,:n].copy()