我有一个数组,它是通过f2py从fortran子程序读取的一维数组。然后在python中,对该数组进行整形:
a=np.zeros(nx*ny*nz)
read_fortran_array(a)
a=a.reshape(nz,ny,nx) #in fortran, the order is a(nx,ny,nz), C/Python it is reversed现在,我想将这个数组作为一个3D数组传递给fortran。
some_data=fortran_routine(a)问题是,f2py在传递给fortran_routine之前一直在尝试转换a。fortran例程看起来如下:
subroutine fortran_routine(nx,ny,nz,a,b)
real a
real b
integer nx,ny,nz
!f2py intent(hidden) nx,ny,nz
!f2py intent(in) a
!f2py intent(out) b
...
end subroutine我怎样才能防止所有的转位来回移动?(我非常乐意在这两种语言中使用不同的数组索引约定)。
编辑
似乎np.asfortranarray或np.flags.f_contiguous应该在解决方案中起一定作用,我只是不知道它是什么部分(或者可能是ravel后面跟着reshape(shape,order='F')
编辑
这篇文章似乎引起了一些混乱。这里的问题是,f2py试图保留索引方案,而不是内存布局。因此,如果我有一个带有(nz, ny, nx)形状的numpy数组(按C顺序),那么f2py也试图使该数组具有fortran中的shape (nz, ny, nx)。如果f2py保留内存布局,则数组将具有python中的(nz, ny, nx)形状和fortran中的(nx, ny ,nz)形状。我想保留内存布局。
发布于 2012-07-02 12:31:06
答案似乎相当简单:
b=np.ravel(a).reshape(tuple(reversed(a.shape)),order='F')起作用,但很明显,这和:
b=a.T因为transpose返回一个视图并快速查看b.flags和a.flags,这表明这是我想要的。(b.flags是F_CONTIGUOUS)。
发布于 2012-06-28 15:55:02
Fortran不反转轴顺序,它只是将数据与C/Python不同地存储在内存中。您可以告诉numpy按Fortran顺序存储数据,这与倒转轴不一样。
我会重写你的代码
a=np.zeros(nx*ny*nz)
read_fortran_array(a)
a=a.reshape(nx,ny,nz, order='F') # It is now in Fortran order现在,f2py不会尝试在传递时重新排序数组。
作为附带说明,这也会起作用。
a=a.reshape(nx,ny,nz) # Store in C order因为在幕后,当您将C命令数组传递给Fortran例程时,f2py执行这些操作:
a=a.flatten() # Flatten array (Make 1-D)
a=a.reshape(nx,ny,nz, order='F') # Place into Fortran order当然,从一开始,在Fortran订单中存储是更有效的。
通常,除非您有一个性能关键部分,否则您不必担心数组的排序,因为f2py会为您处理这个问题。
https://stackoverflow.com/questions/11247934
复制相似问题