如何将 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 中这很容易。
希望对大家有所帮助。
我在 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 中这很容易。
希望对大家有所帮助。