【问题标题】:How to convert numpy ndarray to C float *[]如何将 numpy ndarray 转换为 C float *[]
【发布时间】:2015-12-17 23:55:40
【问题描述】:

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

【问题讨论】:

标签: python c type-conversion swig


【解决方案1】:

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

首先我更改了 .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 函数的数组格式错误,因为我们想要一个双精度数组(在本例中是指向浮点数的指针)。

解决办法是把这个包裹在一维中的数组转换成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];
        }
    }

最后,我可以使用相同的“技巧”将二维浮点数组恢复为 numpy 数组,我确实必须重新调整形状,但在 numpy 中这很容易。

希望对某人有所帮助。

【讨论】:

    【解决方案2】:

    有关于这一点的 SciPy 文档:How to pass numpy arrays to C code via SWIG(反之亦然)。看看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

    【讨论】:

    • 谢谢!虽然我还不知道如何为 float*[] 做这件事,它基本上是一个二维浮点数组..
    • 上面的例子应该适用于二维浮点数组。 float * 不是也将这些引用到第一个元素吗?对不起,我不是“C”人。
    • 它是一个指针数组,不幸的是代码对我不起作用。我还尝试将float* data[] 放在apply 函数中,这似乎传递了引用,但创建了我认为是指针错误,因为它在没有消息的情况下崩溃。
    • 我就是这么想的。提供的函数用于浮点数组(也是 2D)。那也是numpy数组的内部数据结构。如果您需要一个浮点指针数组,那么您需要编写自己的转换函数(通过为 swig 类型映射编写 C 代码)。
    • 好的,非常感谢,您至少让我走上了正轨。我做的很脏,我在c代码中添加了float **data2 = &amp;data;并将标题更改为float *data,这样它就可以匹配正常的typemap了。
    猜你喜欢
    • 2023-03-19
    • 2020-06-27
    • 2017-12-14
    • 2015-08-07
    • 1970-01-01
    • 2021-02-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多