强制numpy数组在物理上匹配内存中的striding

时间:2015-04-17 12:58:36

标签: python numpy fftw stride

对于互相关例程,我想拍摄一些二维矩阵(灰度图像),将它们的一半旋转90度,并对它们进行傅里叶变换。我正在交叉关联大量的帧,所以我试图将pyFFTW与FFTW对象接口一起使用,这在过去已成功使用过。

然而,在这里使用numpy.rot90()我遇到的问题是numpy没有在内存中物理旋转数组而只是改变跨步,而FFTW要求物理内存中的数组实际旋转。

# Import a 2k x 2k image
mage = my_image_import_function( (2048,2048) )
# mage striding is (16384,8)
temp = np.rot90( mage, k=-1 )
# temp striding is (8, -16384 )
temp2 = np.copy( temp )
# temp2 striding is (8, 16384)
mage2 = np.lib.stride_tricks.as_strided( temp2, (2048,2048), (16384,8) )
# mage2 striding is (16384,8)
pyFFTWobj.update_arrays( mage2, mageFFT )
pyFFTWobj.execute()

使用.as_strided()恢复原始步幅,以便将其输入pyFFTW。但是,在应用.as_strided()函数后,mage2不再相对于mage进行轮换。 .as_strided()已撤消旋转操作,因此上述代码不执行任何操作。

程序员如何物理强制一个numpy数组来匹配它在内存中的跨越?

2 个答案:

答案 0 :(得分:2)

您可以强制它在内存中更新,如下所示:

mage=np.random.random((2048,2048))
mage[:] = np.rot90(mage,k=-1)

如果您需要保留mage,可以使用zeros_like在内存中设置另一个数组:

mage2=np.zeros_like(mage)
mage2[:] = np.rot90(mage,k=-1)

答案 1 :(得分:2)

您可以提供np.copy order kwarg来控制复制数组的内存布局。你似乎想要一个C连续的数组,所以你想做:

temp2 = np.copy(temp, order='C')

您可以选择依赖以下事实:order functionnp.copy默认值为'K',相应的method ndarray它是'C',所以这也有效:

temp2 = temp.copy()

当然“明确比隐含更好”以及所有这些,所以即使你采用这种方法,最好明确地询问你想要的东西:

temp2 = temp.copy(order='C')

有些虚假数据,所以看到它有效:

In [36]: a = np.random.randint(256, size=(2048, 2048)).astype(np.uint8)

In [37]: a.strides
Out[37]: (2048, 1)

In [38]: np.rot90(a, k=-1).strides
Out[38]: (1, -2048)
# The method default works...
In [39]: np.rot90(a, k=-1).copy().strides
Out[39]: (2048, 1)
# ...but explicit is better than implicit
In [40]: np.rot90(a, k=-1).copy(order='C').strides
Out[40]: (2048, 1)
# The function default does not work
In [41]: np.rot90(a, k=-1).copy(order='K').strides
Out[41]: (1, 2048)