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

时间:2015-09-21 10:11:48

标签: python c type-conversion swig

我在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多维数组转换为正确的类型呢?

2 个答案:

答案 0 :(得分:1)

有关于此的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

中都解释了这一点

答案 1 :(得分:0)

对于那些可能面临同样问题的人来说,这就是我最终解决的问题。

首先,我更改了.h文件中的标题和

中函数的.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),其中data是一个带有两个维度的 numpy 数组。

“问题”现在是到达C函数的数组格式错误,因为我们需要一个double数组(在这种情况下是一个指向float的指针)。

解决方案是转换这个包含在单个维度中的数组,以重建c代码中的double数组,如下所示:

//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];
        }
    }

最后,我可以使用相同的“技巧”来将二维浮点数组放回到一个numpy数组中,我确实需要重新编译,但是在numpy中很容易。

希望它会对某人有所帮助。