如何将 numpy ndarray 转换为 C float *[]

How to convert numpy ndarray to C float *[]

我在 C 中有代码,我想在 python 中使用它,我使用 SWIG 来包装 C 代码,并得到在我的 python 代码中成功导入了一个 python 模块。

现在我有以下代码:

import flame
import numpy as np

data = np.random.rand(3,2).astype(np.float32, copy=False)
N = 3
M = 2
print data

flameobject = flame.Flame_New()
flame.Flame_SetDataMatrix( flameobject, data, N, M, 0 )

这给出了错误:

TypeError: in method 'Flame_SetDataMatrix', argument 2 of type 'float *[]'

我知道我应该将 float array pointer 传递给该方法,但是如何将我的 Numpy 多维数组转换为正确的类型?

SciPy 文档正是关于此内容:如何通过 SWIG 将 numpy 数组传递给 C 代码(反之亦然)。看看here.

基本上有一个swig接口文件numpy.i,你按下面的方式使用。在您的 swig 接口文件中,您包括:

%{
#define SWIG_FILE_WITH_INIT
%}
%include "numpy.i"
%init %{
import_array();
%}

然后在您的接口文件中添加,在提及您的 C 函数之前:

%apply ( float* IN_ARRAY2, int DIM1, int DIM2 ) {
    (float* your_array_parameter_name, int N_parameter_name, int M_parameter_name)
};

这适用于普通的 C float 数组。我不太确定 float* [] 是什么。您可能需要为此编写自己的类型映射,为此您可以使用 numpy.i 提供的实用程序宏。但是在上面提到的numpy.i文档或者相关的swig typemap docs

中都有解释

好的,对于可能遇到与我相同问题的每个人,这是我最终解决的方法。

首先我更改了 .h 文件中的 header 和

函数的 .c 文件
void Flame_SetDataMatrix( Flame *self, float *data[], int N, int M, int T );

void Flame_SetDataMatrix( Flame *self, float *data, int N, int M, int T );

之后,我添加了

%apply (float* IN_ARRAY2, int DIM1, int DIM2) {
    (float *data, int N, int M)
};

到接口文件(flame.i)。这使得可以像这样调用 Python 中的函数:flame.Flame_SetDataMatrix( flameobject, data, T),其中数据是一个 numpy 数组二维。

现在的"problem"是到达C函数的数组格式错误,因为我们想要一个double数组(在本例中是指向float指针的指针)。

解决方案是将这个包裹在单维中的数组转换为像这样在c代码中重构双精度数组:

//n = number of rows, m= number of columns columns
void Flame_SetDataMatrix( Flame *self, float *data, int n, int m, int dt )
{
    //convert data to float** for later use
    int i=0, j=0;
    float ** data2 = (float**) calloc( n, sizeof(float*) ); 
    for (i=0; i<n; i++){
        data2[i] = calloc( m, sizeof(float) ); 
        for (j=0; j<m; j++){
            //the data is in a single array row after row, so i*columns+j
            data2[i][j] = data[i * m + j];
        }
    }

最后,我可以使用相同的 "trick" 将二维浮点数组返回到 numpy 数组中,我确实必须重新整形,但在 numpy 中这很容易。

希望对大家有所帮助。