设置Numpy中的*默认*数据顺序(C与Fortran)

13 投票
1 回答
3783 浏览
提问于 2025-04-17 05:04

我正在把一些MATLAB的代码移植到Numpy。这项工作包括把一些C++代码中的MEX部分去掉,并用Numpy的C-API中的相应调用来替代。一个问题是,MEX代码把输入的数据当作Fortran顺序来处理,因为MATLAB是按照这种方式来排列它的数组的。而Numpy默认是使用C顺序。

如果不想完全重写MEX代码以适应C顺序,我可以:

  • (A).copy('F')来重新排列进入C代码的数组,用.copy('C')来重新排列输出的数组。
  • (B) 找到方法让Numpy从一开始就“模拟”MATLAB,以Fortran顺序来处理所有操作。

选项A——目前已经实现——运行得很好,但效率非常低。有没有人知道如何让选项B工作?

1 个回答

5

我处理这个问题的方法是,在用f2py把Fortran代码包装起来时,明确声明所有相关的numpy数组为Fortran顺序。这样,numpy可以很顺利地使用这些数组,而且它也能很好地处理Fortran和C顺序的数组。不过,遗憾的是,numpy的操作似乎不会保持Fortran的顺序。因此,你应该提前分配好要传给MEX的目标数组,并确保它们是按照Fortran顺序排列的,比如:

A = np.empty((10, 10))
B = np.empty((10,2))
# fill A and B with the data you want

C = np.empty((10, 2), order='F')
C[:] = np.dot(A, B) # note that this index is essential
# C is then passed to your MEX routine   

我不太确定这样做是否比你的方案A更有效,因为赋值操作会隐含地复制数据。

不过,你不需要重新排列从MEX例程中出来的Fortran数组,只要numpy知道它们的顺序,它就能很顺利地处理这些数组。

撰写回答