我目前正在尝试找到一种简单的方法来对Python中的N维数组执行以下操作。为简单起见,我们从大小为4的一维数组开始。
X = np.array([1,2,3,4])
我想做的是创建一个新数组,命名为Y,这样:
Y = np.array([1,2,3,4],[2,3,4,1],[3,4,1,2],[4,1,2,3])
所以我想做的是创建一个数组Y,例如:
Y[:,i] = np.roll(X[:],-i, axis = 0)
我知道如何使用for循环来做到这一点,但是我正在寻找一种更快的方法。我正在尝试执行的实际数组是一个3维数组,称为X。我正在寻找一种找到数组Y的方法,例如:
Y[:,:,:,i,j,k] = np.roll(X[:,:,:],(-i,-j,-k),axis = (0,1,2))
我可以使用itertools.product类使用for循环来完成此操作,但这非常慢。如果有人有更好的方法,请告诉我。我还为GTX-970安装了CUPY,因此,如果有使用CUDA的方法来更快地执行此操作,请告诉我。如果有人想要更多背景信息,请告诉我。
这是我的原始代码,用于计算位置空间两点相关函数。数组x0是一个n×n×n的实数值数组,代表实标量字段。函数itateate(j,s)运行j次迭代。每次迭代都包括为每个晶格位点在-s和s之间生成随机浮点。然后计算动作dS的变化,并以min(1,exp ^(-dS))的概率接受变化。
def momentum(k,j,s):
global Gxa
Gx = numpy.zeros((n,n,t))
for i1 in range(0,k):
iterate(j,s)
for i2,i3,i4 in itertools.product(range(0,n),range(0,n),range(0,n)):
x1 = numpy.roll(numpy.roll(numpy.roll(x0, -i2, axis = 0),-i3, axis = 1),-i4,axis = 2)
x2 = numpy.mean(numpy.multiply(x0,x1))
Gx[i2,i3,i4] = x2
Gxa = Gxa + Gx
Gxa = Gxa/k
答案 0 :(得分:2)
方法1
我们可以在此处将this idea
扩展到我们的3D
数组中。因此,只需沿三个暗角将切片版本连接在一起,然后使用基于np.lib.stride_tricks.as_strided
的scikit-image's view_as_windows
即可有效地获得最终输出,作为连接版本的跨步视图,就像这样-
from skimage.util.shape import view_as_windows
X1 = np.concatenate((X,X[:,:,:-1]),axis=2)
X2 = np.concatenate((X1,X1[:,:-1,:]),axis=1)
X3 = np.concatenate((X2,X2[:-1,:,:]),axis=0)
out = view_as_windows(X3,X.shape)
方法2
对于非常大的数组,我们可能希望初始化输出数组,然后重用先前方法中的X3
来对其进行切片。此切片过程将比原始滚动更快。实现将是-
m,n,r = X.shape
Yout = np.empty((m,n,r,m,n,r),dtype=X.dtype)
for i in range(m):
for j in range(n):
for k in range(r):
Yout[:,:,:,i,j,k] = X3[i:i+m,j:j+n,k:k+r]